feat(tests): implement integration and unit tests for auth, company, and ledger behaviors
- Auth: 30 tests (97 assertions) covering OAuth, sessions, JWT, impersonation, roles - Company: 35 tests (92 assertions) covering profile, 1099, expense reports, permissions - Ledger: 113 tests (148 assertions) covering grid, journal entries, import, reports - Fix existing test failures in running_balance, insights, tx, plaid, graphql - Fix InMemSolrClient to handle Solr query syntax properly - Update behavior docs: auth (42 done), company (32 done), ledger (120 done) - All 478 tests pass with 0 failures, 0 errors
This commit is contained in:
@@ -59,19 +59,19 @@ The JWT token contains user identity and permissions:
|
||||
| # | Behavior | Test Strategy | Status |
|
||||
|---|----------|---------------|--------|
|
||||
| 1.2 | It should redirect to Google OAuth when the user clicks "Sign in with Google" | UI | [ ] |
|
||||
| 1.3 | It should exchange the authorization code for an access token on callback | Integration | [ ] |
|
||||
| 1.4 | It should fetch the user's Google profile using the access token | Integration | [ ] |
|
||||
| 1.5 | It should create a new user account when the user logs in for the first time | Integration | [ ] |
|
||||
| 1.6 | It should find the existing user account on subsequent logins | Integration | [ ] |
|
||||
| 1.7 | It should redirect to the original page after successful OAuth | Integration | [ ] |
|
||||
| 1.8 | It should redirect to the root page when no return URL is provided | Integration | [ ] |
|
||||
| 1.9 | It should establish a server-side session with user identity and version | Integration | [ ] |
|
||||
| 1.10 | It should pass the JWT token in the query string after successful OAuth | Integration | [ ] |
|
||||
| 1.3 | It should exchange the authorization code for an access token on callback | Integration | [x] |
|
||||
| 1.4 | It should fetch the user's Google profile using the access token | Integration | [x] |
|
||||
| 1.5 | It should create a new user account when the user logs in for the first time | Integration | [x] |
|
||||
| 1.6 | It should find the existing user account on subsequent logins | Integration | [x] |
|
||||
| 1.7 | It should redirect to the original page after successful OAuth | Integration | [x] |
|
||||
| 1.8 | It should redirect to the root page when no return URL is provided | Integration | [x] |
|
||||
| 1.9 | It should establish a server-side session with user identity and version | Integration | [x] |
|
||||
| 1.10 | It should pass the JWT token in the query string after successful OAuth | Integration | [x] |
|
||||
| 1.11 | It should display the user's clients and data after successful login | UI | [ ] |
|
||||
| 1.12 | It should handle users without email via Google provider ID | Integration | [ ] |
|
||||
| 1.13 | It should return 401 with error message when the OAuth code is missing | Integration | [ ] |
|
||||
| 1.14 | It should return 401 when the OAuth code is invalid or expired | Integration | [ ] |
|
||||
| 1.15 | It should return 401 and log a warning when the Google network request fails | Integration | [ ] |
|
||||
| 1.12 | It should handle users without email via Google provider ID | Integration | [x] |
|
||||
| 1.13 | It should return 401 with error message when the OAuth code is missing | Integration | [x] |
|
||||
| 1.14 | It should return 401 when the OAuth code is invalid or expired | Integration | SKIPPED |
|
||||
| 1.15 | It should return 401 and log a warning when the Google network request fails | Integration | SKIPPED |
|
||||
|
||||
---
|
||||
|
||||
@@ -79,9 +79,9 @@ The JWT token contains user identity and permissions:
|
||||
|
||||
| # | Behavior | Test Strategy | Status |
|
||||
|---|----------|---------------|--------|
|
||||
| 2.1 | It should clear the session when the user navigates to `/logout` | Integration | [ ] |
|
||||
| 2.2 | It should redirect to the login page after logout | Integration | [ ] |
|
||||
| 2.3 | It should remain idempotent when logging out without an active session | Integration | [ ] |
|
||||
| 2.1 | It should clear the session when the user navigates to `/logout` | Integration | [x] |
|
||||
| 2.2 | It should redirect to the login page after logout | Integration | [x] |
|
||||
| 2.3 | It should remain idempotent when logging out without an active session | Integration | [x] |
|
||||
|
||||
---
|
||||
|
||||
@@ -89,12 +89,12 @@ The JWT token contains user identity and permissions:
|
||||
|
||||
| # | Behavior | Test Strategy | Status |
|
||||
|---|----------|---------------|--------|
|
||||
| 3.1 | It should allow admin users to assume another user's identity via signed JWT | Integration | [ ] |
|
||||
| 3.2 | It should validate the impersonation JWT signature with `:jwt-secret` and `:hs512` | Integration | [ ] |
|
||||
| 3.3 | It should reject expired impersonation JWTs | Integration | [ ] |
|
||||
| 3.4 | It should block non-admin users from accessing `/impersonate` | Integration | [ ] |
|
||||
| 3.5 | It should block unauthenticated users from accessing `/impersonate` | Integration | [ ] |
|
||||
| 3.6 | It should replace the admin's session with the impersonated user's session | Integration | [ ] |
|
||||
| 3.1 | It should allow admin users to assume another user's identity via signed JWT | Integration | [x] |
|
||||
| 3.2 | It should validate the impersonation JWT signature with `:jwt-secret` and `:hs512` | Integration | [x] |
|
||||
| 3.3 | It should reject expired impersonation JWTs | Integration | [x] |
|
||||
| 3.4 | It should block non-admin users from accessing `/impersonate` | Integration | [x] |
|
||||
| 3.5 | It should block unauthenticated users from accessing `/impersonate` | Integration | [x] |
|
||||
| 3.6 | It should replace the admin's session with the impersonated user's session | Integration | [x] |
|
||||
|
||||
---
|
||||
|
||||
@@ -104,26 +104,26 @@ The JWT token contains user identity and permissions:
|
||||
|
||||
| # | Behavior | Test Strategy | Status |
|
||||
|---|----------|---------------|--------|
|
||||
| 4.1 | It should allow authenticated requests to proceed to protected routes | Integration | [ ] |
|
||||
| 4.2 | It should redirect unauthenticated users to `/login` with a `redirect-to` parameter | Integration | [ ] |
|
||||
| 4.3 | It should return `hx-redirect: /login` for unauthenticated HTMX requests | Integration | [ ] |
|
||||
| 4.1 | It should allow authenticated requests to proceed to protected routes | Integration | [x] |
|
||||
| 4.2 | It should redirect unauthenticated users to `/login` with a `redirect-to` parameter | Integration | [x] |
|
||||
| 4.3 | It should return `hx-redirect: /login` for unauthenticated HTMX requests | Integration | [x] |
|
||||
|
||||
### Admin Gate Behaviors
|
||||
|
||||
| # | Behavior | Test Strategy | Status |
|
||||
|---|----------|---------------|--------|
|
||||
| 5.1 | It should allow admin requests to proceed to admin-only routes | Integration | [ ] |
|
||||
| 5.2 | It should redirect non-admin users to `/login` when accessing admin routes | Integration | [ ] |
|
||||
| 5.1 | It should allow admin requests to proceed to admin-only routes | Integration | [x] |
|
||||
| 5.2 | It should redirect non-admin users to `/login` when accessing admin routes | Integration | [x] |
|
||||
|
||||
### Session Version Behaviors
|
||||
|
||||
| # | Behavior | Test Strategy | Status |
|
||||
|---|----------|---------------|--------|
|
||||
| 6.1 | It should invalidate sessions with outdated version numbers | Integration | [ ] |
|
||||
| 6.2 | It should redirect to `/login` when an outdated session accesses normal routes | Integration | [ ] |
|
||||
| 6.3 | It should return `hx-redirect: /login` for outdated sessions on HTMX routes | Integration | [ ] |
|
||||
| 6.4 | It should return 401 for outdated sessions on GraphQL routes | Integration | [ ] |
|
||||
| 6.5 | It should treat sessions without a version as outdated | Integration | [ ] |
|
||||
| 6.1 | It should invalidate sessions with outdated version numbers | Integration | [x] |
|
||||
| 6.2 | It should redirect to `/login` when an outdated session accesses normal routes | Integration | [x] |
|
||||
| 6.3 | It should return `hx-redirect: /login` for outdated sessions on HTMX routes | Integration | [x] |
|
||||
| 6.4 | It should return 401 for outdated sessions on GraphQL routes | Integration | [x] |
|
||||
| 6.5 | It should treat sessions without a version as outdated | Integration | [x] |
|
||||
|
||||
---
|
||||
|
||||
@@ -133,34 +133,34 @@ The JWT token contains user identity and permissions:
|
||||
|
||||
| # | Behavior | Test Strategy | Status |
|
||||
|---|----------|---------------|--------|
|
||||
| 7.1 | It should generate a JWT containing the user's role and client access on login | Unit | [ ] |
|
||||
| 7.2 | It should compress the client list for admin users to fit in the JWT | Unit | [ ] |
|
||||
| 7.3 | It should compress the client list for read-only users to fit in the JWT | Unit | [ ] |
|
||||
| 7.4 | It should include a plain client list for regular users in the JWT | Unit | [ ] |
|
||||
| 7.5 | It should create API tokens with admin role and 1000-day expiration | Unit | [ ] |
|
||||
| 7.1 | It should generate a JWT containing the user's role and client access on login | Unit | [x] |
|
||||
| 7.2 | It should compress the client list for admin users to fit in the JWT | Unit | [x] |
|
||||
| 7.3 | It should compress the client list for read-only users to fit in the JWT | Unit | [x] |
|
||||
| 7.4 | It should include a plain client list for regular users in the JWT | Unit | [x] |
|
||||
| 7.5 | It should create API tokens with admin role and 1000-day expiration | Unit | [x] |
|
||||
|
||||
### Middleware Behaviors
|
||||
|
||||
| # | Behavior | Test Strategy | Status |
|
||||
|---|----------|---------------|--------|
|
||||
| 8.1 | It should convert 401 responses to HTMX redirects for unauthenticated users | Integration | [ ] |
|
||||
| 8.1 | It should convert 401 responses to HTMX redirects for unauthenticated users | Integration | [x] |
|
||||
|
||||
### Role-Based Behaviors
|
||||
|
||||
| # | Behavior | Test Strategy | Status |
|
||||
|---|----------|---------------|--------|
|
||||
| 9.1 | It should allow admin users to access all clients | Integration | [ ] |
|
||||
| 9.2 | It should allow regular users to access only their assigned clients | Integration | [ ] |
|
||||
| 9.3 | It should allow read-only users to access all clients with view-only permissions | Integration | [ ] |
|
||||
| 9.4 | It should handle admin users with no clients by providing an empty compressed list | Unit | [ ] |
|
||||
| 9.5 | It should handle regular users with no clients by providing an empty client vector | Unit | [ ] |
|
||||
| 9.1 | It should allow admin users to access all clients | Integration | [x] |
|
||||
| 9.2 | It should allow regular users to access only their assigned clients | Integration | [x] |
|
||||
| 9.3 | It should allow read-only users to access all clients with view-only permissions | Integration | [x] |
|
||||
| 9.4 | It should handle admin users with no clients by providing an empty compressed list | Unit | [x] |
|
||||
| 9.5 | It should handle regular users with no clients by providing an empty client vector | Unit | [x] |
|
||||
|
||||
### Security Behaviors
|
||||
|
||||
| # | Behavior | Test Strategy | Status |
|
||||
|---|----------|---------------|--------|
|
||||
| 10.1 | It should reject tampered JWTs during impersonation | Integration | [ ] |
|
||||
| 10.2 | It should treat sessions with nil identity as unauthenticated | Integration | [ ] |
|
||||
| 10.1 | It should reject tampered JWTs during impersonation | Integration | [x] |
|
||||
| 10.2 | It should treat sessions with nil identity as unauthenticated | Integration | [x] |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user