> translate-press-zone-api@1.0.0 test > jest --runInBand PASS __tests__/integration/routes/webhooks.test.ts (6.405 s) POST /v1/webhooks/paypal Signature verification ✓ returns 200 when signature is valid (44 ms) ✓ returns 401 when signature verification fails (32 ms) ✓ returns 401 when signature verification fails due to tampered body (20 ms) ✓ returns 401 and makes no DB calls when headers are missing (21 ms) Idempotency ✓ returns { duplicate: true } on sequential replay and credits are allocated only once (30 ms) ✓ credits are allocated exactly once on concurrent replay (Promise.all) (44 ms) BILLING.SUBSCRIPTION.ACTIVATED session-backed path (custom_id present) ✓ creates subscription with session plugin and allocates credits (22 ms) ✓ session status is flipped to paid and stays paid on second distinct ACTIVATED event (38 ms) legacy email-lookup path (no session) ✓ creates subscription with plugin=translate when user found by email (17 ms) ✓ returns 200 with no side-effects when email is unknown (17 ms) ✓ returns 200 with no side-effects when no session and no email in payload (42 ms) BILLING.SUBSCRIPTION.CANCELLED ✓ transitions subscription to cancelled status (19 ms) ✓ returns 200 without error when subscription is not found (39 ms) BILLING.SUBSCRIPTION.SUSPENDED ✓ transitions subscription to suspended status (14 ms) BILLING.SUBSCRIPTION.UPDATED ✓ updates tier and billing cycle when plan_id changes (14 ms) ✓ returns 200 without update when subscription is not found (13 ms) PAYMENT.SALE.COMPLETED ✓ creates Payment row, advances billing period, and allocates credits (30 ms) ✓ bumps retry_count and does NOT re-allocate credits on duplicate paypal_payment_id (14 ms) ✓ returns 200 with no side-effects when subscription is not found (30 ms) PAYMENT.SALE.REFUNDED ✓ marks original payment refunded, creates refund record, and reverses credits (14 ms) ✓ returns 200 with no side-effects when original payment is not found (28 ms) Unhandled event type ✓ returns 200 without any DB writes for an unknown event type (14 ms) PASS src/__tests__/unit/services/translationService.test.ts TranslationService translateSync ✓ translates successfully and persists the provider-selected model (3 ms) ✓ rejects content above the synchronous character limit (35 ms) ✓ rejects empty content (4 ms) ✓ checks character credits before creating a job (5 ms) ✓ returns a complete cached response without calling Gemini or deducting credits (4 ms) ✓ marks the job failed when the provider call fails (5 ms) ✓ does not persist a caller-selected model on the job claim (4 ms) ✓ defaults the tone when callers omit it (4 ms) translateAsync ✓ claims and queues an asynchronous job atomically (6 ms) ✓ rejects content above the asynchronous character limit (4 ms) ✓ rejects empty content (4 ms) ✓ checks character credits before entering the transaction (4 ms) ✓ returns an existing pending duplicate without queueing another job (4 ms) ✓ returns an existing processing duplicate without queueing another job (4 ms) ✓ scopes deduplication and job creation to the plugin (4 ms) ✓ includes callback identity in deduplication and queue payloads (21 ms) ✓ scopes idempotency to the authenticated site (4 ms) ✓ defaults the async tone without adding a model field (5 ms) getJobStatus ✓ maps a completed job including character and cost fields (4 ms) ✓ throws when the job does not exist (5 ms) ✓ throws when the job belongs to another user (4 ms) ✓ omits zero-valued completion fields for pending jobs (5 ms) ✓ returns the error message for failed jobs (4 ms) cancelJob ✓ cancels a pending job using a compare-and-set update (25 ms) ✓ throws when the job to cancel does not exist (5 ms) ✓ throws when cancelling another user’s job (5 ms) ✓ rejects a job owned by another authenticated site scope (5 ms) ✓ rejects a job owned by another authenticated plugin scope (12 ms) ✓ allows an in-flight processing job to be cancelled (5 ms) ✓ returns an already-cancelled job without another mutation (5 ms) ✓ returns a concurrently cancelled job after losing the compare-and-set race (5 ms) ✓ rejects a completed job without mutation (5 ms) ✓ rejects a failed job without mutation (24 ms) retryJob ✓ resets and queues a failed job with its original request data (6 ms) ✓ throws when the job to retry does not exist (5 ms) ✓ throws when retrying another user’s job (5 ms) ✓ rejects retrying a pending job (7 ms) ✓ rejects retrying a processing job (6 ms) ✓ rejects retrying a completed job (6 ms) ✓ reconstructs structured fields instead of queueing the serialized payload as content (5 ms) getJobs ✓ returns paginated jobs with default options (27 ms) ✓ filters client job lookup by authenticated site (6 ms) ✓ filters by a single status (6 ms) ✓ filters by multiple statuses (5 ms) ✓ supports custom pagination (5 ms) ✓ supports sorting by updated_at ascending (6 ms) ✓ maps character, internal-cost, and customer-cost fields (5 ms) ✓ omits zero-valued optional fields (27 ms) ✓ handles an empty result set (19 ms) ✓ combines filtering, pagination, and sorting in one query (6 ms) concurrency and transaction errors ✓ keeps two independent synchronous requests isolated (6 ms) ✓ propagates an async claim failure without creating or queueing a job (6 ms) PASS src/__tests__/unit/services/paypalService.test.ts PayPal Service createSubscription ✓ should create a subscription successfully (2 ms) ✓ should throw error if user not found (20 ms) ✓ should throw error if invalid plan tier (4 ms) ✓ should throw error if no approval URL returned (2 ms) ✓ should handle PayPal API errors (2 ms) cancelSubscription ✓ should cancel subscription successfully (2 ms) ✓ should throw error if subscription not found (7 ms) ✓ should throw error if subscription belongs to different user (4 ms) ✓ should handle already cancelled subscription (4 ms) getSubscriptionDetails ✓ should get subscription details successfully (16 ms) ✓ should throw error if subscription not found (4 ms) verifyWebhookSignature ✓ should verify valid signature (4 ms) ✓ should reject invalid signature (3 ms) ✓ should return false if transmission-id header missing (4 ms) ✓ should return false if transmission-time header missing (4 ms) ✓ should return false if cert-url header missing (5 ms) ✓ should return false if auth-algo header missing (4 ms) ✓ should return false if transmission-sig header missing (4 ms) ✓ should handle verification API errors (3 ms) handleWebhookEvent - BILLING.SUBSCRIPTION.ACTIVATED ✓ should handle subscription activated event (5 ms) ✓ should reject event with invalid signature (5 ms) ✓ should throw error if user ID not found (4 ms) handleWebhookEvent - PAYMENT.SALE.COMPLETED ✓ should handle payment completed event (5 ms) ✓ should handle payment when subscription not found (6 ms) handleWebhookEvent - BILLING.SUBSCRIPTION.CANCELLED ✓ should handle subscription cancelled event (11 ms) handleWebhookEvent - BILLING.SUBSCRIPTION.SUSPENDED ✓ should handle subscription suspended event (6 ms) handleWebhookEvent - BILLING.SUBSCRIPTION.EXPIRED ✓ should handle subscription expired event (6 ms) handleWebhookEvent - BILLING.SUBSCRIPTION.UPDATED ✓ should handle subscription updated event (5 ms) ✓ should handle updated event without plan_id (5 ms) handleWebhookEvent - Unknown Event Type ✓ should handle unknown event type gracefully (25 ms) Edge Cases and Error Handling ✓ should handle database errors in subscription creation (5 ms) ✓ should handle network errors in PayPal API calls (4 ms) ✓ should handle credit allocation errors during activation (5 ms) PASS src/__tests__/integration/routes/admin.test.ts Admin Routes Admin Authentication POST /v1/admin/auth/login ✓ should successfully login with valid admin credentials (500 ms) ✓ should reject login with invalid credentials (485 ms) ✓ should reject non-admin users from admin login (7 ms) ✓ should return admin JWT token (475 ms) User Management GET /v1/admin/users ✓ should list all users with pagination (8 ms) ✓ should filter users by status (6 ms) ✓ should return 401 for non-admin access (5 ms) GET /v1/admin/users/:id ✓ should get specific user details (9 ms) PATCH /v1/admin/users/:id ✓ should update user status (7 ms) POST /v1/admin/users/:id/suspend ✓ should suspend user account (9 ms) Job Management GET /v1/admin/jobs ✓ should list all translation jobs (26 ms) ✓ should filter jobs by status (10 ms) ✓ should filter jobs by user (10 ms) ✓ should paginate correctly (10 ms) GET /v1/admin/jobs/:id ✓ should get job details (37 ms) Transaction Management GET /v1/admin/transactions ✓ should list all transactions with pagination (11 ms) ✓ should filter by user (11 ms) ✓ should filter by date range (11 ms) GET /v1/admin/transactions/:id ✓ should get transaction details with payment info (11 ms) Analytics GET /v1/admin/analytics/dashboard ✓ should get dashboard metrics (31 ms) GET /v1/admin/analytics/revenue ✓ should get revenue statistics (32 ms) GET /v1/admin/analytics/usage ✓ should get usage stats (14 ms) GET /v1/admin/analytics/jobs ✓ should aggregate job metrics by target language (33 ms) Settings Management GET /v1/admin/settings ✓ should get all settings (14 ms) PATCH /v1/admin/settings ✓ should update setting value (16 ms) ✓ should validate setting types with Zod schemas (39 ms) 2026-08-23 09:45:41 [error]: Sync translation error { "service": "translate-api", "error": {}, "userId": "user_test_123", "requestId": "req_1787467541545_5fg7jap3s" } 2026-08-23 09:45:41 [error]: Async job submission error { "service": "translate-api", "error": {}, "userId": "user_test_123", "requestId": "req_1787467541735_92z92asf7" } 2026-08-23 09:45:41 [error]: Job status retrieval error { "service": "translate-api", "error": {}, "userId": "user_test_123", "jobId": "00000000-0000-4000-8000-000000000051", "requestId": "req_1787467541781_cix86uki5" } 2026-08-23 09:45:41 [error]: Job status retrieval error { "service": "translate-api", "error": {}, "userId": "user_test_123", "jobId": "00000000-0000-4000-8000-000000000052", "requestId": "req_1787467541793_84dttfqf7" } 2026-08-23 09:45:42 [error]: Job retry error { "service": "translate-api", "error": {}, "userId": "user_test_123", "jobId": "00000000-0000-4000-8000-000000000071", "requestId": "req_1787467542021_1ybnvziay" } PASS src/__tests__/integration/routes/translate.test.ts Translation Routes POST /v1/translate - Synchronous Translation ✓ should translate successfully with valid API key and sufficient credits (13 ms) ✓ should return 401 without API key (14 ms) ✓ should return 401 for an unknown API key (27 ms) ✓ should return 402 insufficient credits (17 ms) ✓ should return 400 for content exceeding sync limit (5000 chars) (17 ms) ✓ should return 400 for invalid language codes (15 ms) ✓ should return cached translation for duplicate content (16 ms) ✓ should ignore an unrecognized model field (model selection is code-driven, not client-supplied) (38 ms) ✓ should validate tone parameter (12 ms) POST /v1/jobs - Asynchronous Translation ✓ should submit async job successfully (13 ms) ✓ should submit job with client job ID (12 ms) ✓ should prevent duplicate job submission (31 ms) ✓ should reject content exceeding async limit (50000 chars) (15 ms) ✓ should return 402 for insufficient credits (21 ms) GET /v1/jobs/:jobId - Job Status ✓ should get job status successfully (33 ms) ✓ should return 404 for non-existent job (11 ms) ✓ should return 403 for unauthorized access (different user) (11 ms) ✓ should return completed job with translation (11 ms) ✓ should return failed job with error message (28 ms) ✓ should validate UUID format for job ID (12 ms) POST /v1/jobs/:jobId/cancel - Cancel Job ✓ rejects cancellation when API-key authentication has no bound site (12 ms) POST /v1/estimate - Token Estimation ✓ should estimate tokens for single language successfully (30 ms) ✓ should estimate tokens for multiple languages (12 ms) ✓ should validate content length (13 ms) ✓ should validate language codes (12 ms) ✓ should validate target_langs is non-empty array (43 ms) ✓ should limit target languages to maximum 20 (12 ms) POST /v1/jobs/:jobId/retry - Retry Failed Job ✓ should retry failed job successfully (12 ms) ✓ should return 400 when trying to retry non-failed job (30 ms) GET /v1/jobs - List Jobs ✓ should list all jobs for authenticated user (11 ms) ✓ should filter jobs by status (12 ms) ✓ should paginate results (12 ms) PASS src/__tests__/integration/routes/account.test.ts Account Routes GET /v1/account (Profile) ✓ should get authenticated user profile with subscription (17 ms) ✓ should return 401 for missing token (6 ms) ✓ should return 401 for invalid token (6 ms) GET /v1/account/credits ✓ should get current credit balance with subscription (7 ms) ✓ should handle users with no credit transactions (7 ms) ✓ should handle users without subscription (6 ms) ✓ should return 401 for unauthenticated requests (6 ms) ✓ should return 401 for an unknown API key (7 ms) GET /v1/account/usage ✓ should get usage statistics with pagination (7 ms) ✓ should apply pagination correctly (26 ms) ✓ should return empty usage for new accounts (8 ms) GET /v1/account subscription payload ✓ should get active subscription details (9 ms) ✓ should return an empty subscription list for users without subscription (14 ms) ✓ should include plan tier and billing cycle (9 ms) ✓ should show next billing date (27 ms) API Keys Management POST /v1/account/api-keys ✓ should create new API key with name (11 ms) ✓ should validate key name requirements (10 ms) GET /v1/account/api-keys ✓ should list all user API keys without secrets (9 ms) DELETE /v1/account/api-keys/:keyId ✓ should revoke API key (10 ms) ✓ should return 404 for non-existent keys without mutating anything (26 ms) ✓ should ensure user can only access their own keys (16 ms) PASS src/__tests__/unit/services/settingsService.test.ts Settings Service getSystemSettings ✓ should fetch settings from database on cache miss (2 ms) ✓ should use cached settings on subsequent calls (cache hit) (1 ms) ✓ should auto-refresh cache after TTL expires (2 ms) ✓ should return empty map when no settings exist (2 ms) ✓ should handle database errors (12 ms) getSetting ✓ should return setting value when found (2 ms) ✓ should return undefined when setting not found (1 ms) ✓ should support type casting (2 ms) ✓ should work with string keys (2 ms) getSettingWithDefault ✓ should return setting value when found (2 ms) ✓ should return default value when setting not found (1 ms) ✓ should return default value when setting is undefined (2 ms) ✓ should work with numeric defaults (2 ms) ✓ should work with boolean defaults (1 ms) updateSetting ✓ should update setting in database and cache (3 ms) ✓ should create new setting if not exists (3 ms) ✓ should update cache immediately (2 ms) ✓ should handle database errors (3 ms) ✓ should handle null/undefined values (2 ms) deleteSetting ✓ should delete setting from database and cache (3 ms) ✓ should handle database errors (3 ms) ✓ should work with string keys (3 ms) forceRefresh ✓ should force cache refresh from database (3 ms) ✓ should refresh even when cache is not expired (4 ms) getGeminiConfig ✓ should return Gemini config when API key exists (3 ms) ✓ should return undefined when API key missing (2 ms) getPayPalConfig ✓ returns complete PayPal credentials without requiring legacy plan settings (3 ms) ✓ should return undefined when any required setting is missing (3 ms) ✓ returns undefined when PayPal mode is invalid (3 ms) getPricingConfig ✓ should return pricing from settings (18 ms) ✓ should return default pricing when not configured (3 ms) getCreditAllocations ✓ should return credit allocations from settings (3 ms) ✓ should return default allocations when not configured (4 ms) matchesSettingVersions ✓ rejects an acknowledgement after a setting is overwritten (3 ms) getRateLimits ✓ should return rate limits from settings (3 ms) ✓ should return default rate limits when not configured (3 ms) 2026-08-23 09:45:43 [error]: Failed to send welcome email { "service": "translate-api", "error": {}, "email": "user@example.com" } 2026-08-23 09:45:43 [error]: Failed to send verification email { "service": "translate-api", "error": {}, "email": "user@example.com" } 2026-08-23 09:45:43 [error]: Failed to send password reset email { "service": "translate-api", "error": {}, "email": "user@example.com" } 2026-08-23 09:45:43 [error]: Failed to send low credit warning { "service": "translate-api", "error": {}, "email": "user@example.com" } 2026-08-23 09:45:43 [error]: Failed to send subscription receipt { "service": "translate-api", "error": {}, "email": "user@example.com" } 2026-08-23 09:45:43 [error]: Failed to send job completion email { "service": "translate-api", "email": "user@example.com", "jobId": "job_123", "error": {} } 2026-08-23 09:45:43 [error]: Failed to send low credit warning { "service": "translate-api", "error": {}, "email": "user@example.com" } 2026-08-23 09:45:43 [error]: Failed to send welcome email { "service": "translate-api", "error": {}, "email": "invalid-email" } 2026-08-23 09:45:43 [error]: Failed to send subscription receipt { "service": "translate-api", "error": {}, "email": "user@example.com" } PASS src/__tests__/unit/services/emailService.test.ts Email Service sendWelcomeEmail ✓ should send welcome email successfully (2 ms) ✓ should include user name in email content (1 ms) ✓ should include call-to-action link ✓ should handle SendGrid errors gracefully (1 ms) ✓ should return false when SendGrid not configured (1 ms) sendVerificationEmail ✓ should send verification email successfully ✓ should include verification URL with token (1 ms) ✓ should include clickable verification button ✓ should throw error on SendGrid failure (11 ms) ✓ should return false when SendGrid not configured (1 ms) sendPasswordResetEmail ✓ should send password reset email successfully ✓ should include reset URL with token ✓ should include expiration warning (1 ms) ✓ should include reset button ✓ should throw error on SendGrid failure (1 ms) ✓ should return false when SendGrid not configured sendLowCreditWarning ✓ should send low credit warning successfully (214 ms) ✓ should format credit numbers with locale formatting (1 ms) ✓ should include upgrade link ✓ should handle zero credits (1 ms) ✓ should return false on SendGrid error ✓ should return false when SendGrid not configured sendSubscriptionReceipt ✓ should send subscription receipt successfully (26 ms) ✓ should format amount as currency ✓ should include plan tier (1 ms) ✓ should include current date ✓ should include dashboard link (1 ms) ✓ should return false on SendGrid error ✓ should return false when SendGrid not configured ✓ should handle decimal amounts correctly sendJobCompletionEmail ✓ should send job completion email successfully ✓ should display language codes in uppercase (1 ms) ✓ should include abbreviated job ID ✓ should include completion checkmark ✓ should return false on SendGrid error (1 ms) ✓ should return false when SendGrid not configured ✓ should handle various language codes Email Template Structure ✓ should use consistent HTML styling ✓ should include from name and email (1 ms) ✓ should provide both text and HTML versions Error Handling ✓ should handle network timeouts ✓ should handle invalid email addresses gracefully (1 ms) ✓ should handle SendGrid rate limiting (1 ms) 2026-08-23 09:45:43 [error]: Failed to get current balance { "service": "translate-api", "userId": "user_789", "error": {} } 2026-08-23 09:45:43 [error]: Failed to deduct credits { "service": "translate-api", "userId": "user_123", "amount": 1000, "description": "Translation job", "error": {} } PASS src/__tests__/unit/services/creditService.test.ts Credit Service getCurrentBalance ✓ should return latest balance from transaction history (2 ms) ✓ should return 0 if no transactions exist (1 ms) ✓ should handle database errors (11 ms) allocateCredits ✓ should allocate credits successfully (2 ms) ✓ should reject negative allocation amount (4 ms) ✓ should reject zero allocation amount (3 ms) ✓ should include payment ID when provided (3 ms) deductCredits ✓ should deduct credits successfully (3 ms) ✓ should reject deduction when insufficient credits (2 ms) ✓ should reject negative deduction amount (2 ms) ✓ should reject zero deduction amount (2 ms) ✓ should allow exact balance deduction (2 ms) refundCredits ✓ should refund credits successfully (2 ms) ✓ should reject negative refund amount (1 ms) ✓ should reject zero refund amount (1 ms) hasSufficientCredits ✓ should return true when credits are sufficient (2 ms) ✓ should return false when credits are insufficient (1 ms) ✓ should return true when balance exactly matches required (2 ms) ✓ should return false when balance is zero (1 ms) getCreditHistory ✓ should return paginated credit history (2 ms) ✓ should support custom limit and offset (4 ms) ✓ should return empty array when no transactions (20 ms) CreditTransaction shape returned to callers ✓ maps deductCredits to the camelCase CreditTransaction contract (3 ms) ✓ maps allocateCredits to the camelCase CreditTransaction contract (2 ms) ✓ maps refundCredits to the camelCase CreditTransaction contract (2 ms) ✓ maps getCreditHistory rows to the camelCase CreditTransaction contract (2 ms) calculateCreditCost ✓ should return characters as credits (1:1 ratio) (2 ms) PASS src/__tests__/unit/config/configUpdates.test.ts Redis configuration ✓ builds valid URLs with empty and non-empty passwords (1 ms) ✓ keeps complete PayPal environment fallback during refresh (2 ms) publishConfigUpdate ✓ returns only after every live worker acknowledges the exact version (2 ms) ✓ does not treat Redis subscriber count as worker application (20 ms) ✓ rejects when no healthy workers are registered (1 ms) startConfigSubscription ✓ acknowledges a version only after applying its exact categories (2 ms) ✓ does not acknowledge a version when refresh fails (1 ms) ✓ serializes startup replay and live updates in arrival order (1 ms) ✓ reports readiness only after replay and acknowledgement Redis are healthy (2 ms) ✓ acknowledges updates for categories the worker does not consume (1 ms) ✓ does not acknowledge when persisted setting versions no longer match the update (1 ms) PASS src/__tests__/unit/services/geminiClient.test.ts GeminiClient translate() Success scenarios ✓ should translate simple text successfully (2 ms) ✓ should preserve HTML tags in translation (1 ms) ✓ should preserve complex nested HTML tags ✓ should preserve self-closing tags (1 ms) ✓ should preserve HTML tag attributes with quotes (1 ms) Tone variations ✓ should use formal tone instruction ✓ should use casual tone instruction (1 ms) ✓ should use neutral tone instruction ✓ should default to neutral tone if not specified Language support ✓ should convert language codes to readable names in prompt (1 ms) ✓ should handle less common language codes ✓ should use uppercase code for unknown languages (1 ms) ✓ should handle Asian languages correctly Token counting ✓ should count input and output tokens separately (1 ms) ✓ should handle zero token responses (20 ms) Error handling ✓ should handle authentication errors (401) (1 ms) ✓ should handle rate limit errors (429) (1 ms) ✓ should handle rate limit with alternate message ✓ should handle timeout errors (3 ms) ✓ should handle model unavailable errors (503) (1 ms) ✓ should handle generic API errors (1 ms) ✓ should handle empty translation response ✓ should handle null translation response (1 ms) ✓ should handle non-Error exceptions (1 ms) healthCheck() ✓ should return true when service is healthy ✓ should return false when service is unavailable (1 ms) ✓ should return false on timeout (1 ms) ✓ should return false when response is empty ✓ should return false when response is null Configuration refresh ✓ should refresh config when Gemini settings change ✓ should get current config status 2026-08-23 09:45:47 [error]: Token refresh error { "service": "translate-api", "error": {} } PASS src/__tests__/integration/routes/auth.test.ts Auth Routes POST /v1/auth/register ✓ should register a new user successfully (234 ms) ✓ should reject registration with existing email (7 ms) ✓ should validate email format (6 ms) ✓ should validate password length (5 ms) ✓ should reject missing email (5 ms) ✓ should reject missing password (4 ms) POST /v1/auth/login ✓ should login successfully with valid credentials (445 ms) ✓ should reject login with invalid email (5 ms) ✓ should reject login with invalid password (445 ms) ✓ should reject login for suspended account (448 ms) ✓ should handle user without subscription (464 ms) POST /v1/auth/refresh ✓ should refresh access token with valid refresh token (6 ms) ✓ should reject expired refresh token (5 ms) ✓ should reject refresh for suspended account (5 ms) ✓ should reject refresh for non-existent user (5 ms) POST /v1/auth/verify-email ✓ should verify email with valid token (4 ms) ✓ should reject invalid verification token (6 ms) POST /v1/auth/forgot-password ✓ should send password reset for existing user (5 ms) ✓ should return same message for non-existent user (security) (6 ms) ✓ should validate email format (18 ms) POST /v1/auth/reset-password ✓ should reset password with valid token (250 ms) ✓ should reject expired reset token (6 ms) ✓ should validate new password length (5 ms) PASS src/__tests__/integration/routes/updates.test.ts Plugin update delivery POST /v1/international/updates/check ✓ rejects an unauthenticated check without leaking release metadata (22 ms) ✓ rejects an unknown license exactly as the sibling licensing routes do (5 ms) ✓ rejects an expired license (5 ms) ✓ rejects a license that is not activated for the requesting site (8 ms) ✓ reports no update when the installed version is already the latest (6 ms) ✓ compares versions numerically rather than lexically (5 ms) ✓ offers the highest version even when a patch was published later (5 ms) ✓ keeps the license key out of the request log for the GET form (6 ms) ✓ returns every field the WordPress update transient needs (5 ms) ✓ only offers a release the license plan tier is entitled to (5 ms) ✓ mints a signed, expiring package URL that carries no license key (5 ms) ✓ accepts the transitional GET form for already-installed sites (5 ms) ✓ resolves the site from the plugin User-Agent when no site_url is sent (5 ms) ✓ fails closed when the site cannot be resolved at all (5 ms) POST /v1/international/updates/verify ✓ confirms a package whose digest matches an entitled release (5 ms) ✓ resolves the release by hash, never by the client-supplied version (7 ms) ✓ returns a definite valid:false for an unknown digest (5 ms) ✓ rejects a malformed digest rather than answering ambiguously (5 ms) ✓ rejects verification for a site the license is not activated on (5 ms) PASS src/__tests__/unit/services/translationServiceStructured.test.ts async structured service propagation ✓ stores canonical fields, charges every value, and queues the same map (3 ms) ✓ reuses only exact client and callback identity for pending jobs (4 ms) ✓ claims exact concurrent submissions once and enqueues once (4 ms) ✓ rejects completed state without mutation (22 ms) ✓ reports cancellation persistence failure instead of claiming cancellation (5 ms) ✓ persists and queues segmented Site Content without exposing attempt authority (5 ms) ✓ restores segmented retry context but never returns the attempt token from polling (6 ms) ✓ exposes legacy aliases and custom translated fields from canonical output (5 ms) ✓ keeps legacy JSON translation blobs opaque (4 ms) ✓ reconstructs signed webhook data with aliases and translatedFields (20 ms) PASS src/__tests__/unit/utils/encryption.test.ts Encryption Utils hashPassword ✓ should hash a password (240 ms) ✓ should generate different hashes for same password (484 ms) ✓ should handle empty password (241 ms) ✓ should handle special characters (241 ms) verifyPassword ✓ should verify correct password (480 ms) ✓ should reject incorrect password (478 ms) ✓ should reject empty password against hash (477 ms) ✓ should handle case sensitivity (474 ms) generateApiKey ✓ should generate API key with default prefix ✓ should generate API key with custom prefix (1 ms) ✓ should generate unique keys ✓ should generate deterministic hash for same key (1 ms) hashApiKey ✓ should hash API key using SHA-256 ✓ should produce consistent hashes ✓ should produce different hashes for different keys ✓ should be case sensitive generateToken ✓ should generate token with default length (1 ms) ✓ should generate token with custom length ✓ should generate unique tokens ✓ should handle small length (1 ms) generateWebhookSignature ✓ should generate HMAC signature ✓ should generate consistent signatures for same input (1 ms) ✓ should generate different signatures for different inputs ✓ should generate different signatures for different secrets verifyWebhookSignature ✓ should verify valid signature ✓ should reject invalid signature ✓ should reject signature with wrong secret ✓ should reject signature with modified timestamp generateContentHash ✓ should generate content hash (1 ms) ✓ should generate consistent hashes for same input ✓ should generate different hashes for different content ✓ should generate different hashes for different languages ✓ should handle empty content (1 ms) generateWebhookSecret ✓ should generate webhook secret ✓ should generate unique secrets ✓ should generate cryptographically random secrets (1 ms) PASS src/__tests__/unit/auth/jwtService.test.ts JWT Service generateAccessToken ✓ should generate valid access token (2 ms) ✓ should include user data in token payload (2 ms) ✓ should include issuer and audience claims (1 ms) ✓ should include expiration time ✓ should generate different tokens for different users (1 ms) generateRefreshToken ✓ should generate valid refresh token (1 ms) ✓ should include minimal payload (1 ms) ✓ should have longer expiration than access token (1 ms) ✓ should generate different tokens each time (1 ms) verifyAccessToken ✓ should verify valid access token (2 ms) ✓ should reject expired token (15 ms) ✓ should reject token with invalid signature (2 ms) ✓ should reject token with wrong type (1 ms) ✓ should reject malformed token (1 ms) ✓ should reject empty token (1 ms) verifyRefreshToken ✓ should verify valid refresh token (1 ms) ✓ should reject expired refresh token (1 ms) ✓ should reject token with invalid signature (1 ms) ✓ should reject access token as refresh token (1 ms) extractTokenFromHeader ✓ should extract token from valid Authorization header ✓ should return null for missing header (1 ms) ✓ should return null for header without Bearer prefix ✓ should return null for malformed Bearer header ✓ should return null for wrong authentication scheme (1 ms) ✓ should return null for empty header ✓ should reject header with extra spaces Token integration ✓ should support full access token flow (1 ms) ✓ should support full refresh token flow (1 ms) ✓ should maintain user identity through token renewal (1 ms) PASS src/__tests__/unit/queue/bulkQueueDispatcher.test.ts bulk queue dispatcher ✓ excludes every database-null payload batch and immediately queues a later persisted payload (2 ms) ✓ drains a committed job after submission dies before its first enqueue (1 ms) ✓ starts immediately, schedules bounded recurring drains, and stops cleanly (1 ms) ✓ claims concurrently drained rows once (1 ms) ✓ recovers an expired post-add lease with Bull stable jobId ✓ releases a failed enqueue for bounded recurring retry (1 ms) ✓ skips cancelled rows (1 ms) ✓ skips processing rows ✓ skips completed rows ✓ skips failed rows (1 ms) ✓ keeps the callback secret out of stored payload and passes exact secret to Bull ✓ maps Prisma claimed-row callback_secret to Bull callbackSecret after atomic claim (1 ms) PASS src/__tests__/unit/workerSiteContent.test.ts segmented Site Content worker ✓ settles translated segments and persists callback attempt authority in the outbox (5 ms) ✓ returns bounded generic failure data while preserving callback attempt authority (25 ms) ✓ redacts provider failures before Bull persists a retry failure reason (6 ms) ✓ replays a completed terminal job without provider or billing work (6 ms) PASS src/__tests__/unit/routes/settingsConfigPropagation.test.ts admin settings config propagation ✓ refreshes the API and publishes deduplicated categories to workers (1 ms) ✓ does not publish settings without a dynamic config mapping ✓ rejects when worker publication fails (13 ms) ✓ still publishes when the local refresh fails (1 ms) ✓ returns 503 after persisting settings when propagation fails (8 ms) ✓ returns 503 after persisting a single setting when propagation fails (5 ms) ✓ rejects support-role access to system settings (8 ms) ✓ keeps credential values write-only in GET, PATCH, and PUT responses (9 ms) ✓ redacts credential-like values from audit and application logs (6 ms) PASS src/__tests__/unit/workerBulkContent.test.ts bulk-content worker ✓ translates every item with one Gemini call each and delivers one webhook with per-item results (4 ms) ✓ isolates a single item failure without aborting the batch, and bills only successes (5 ms) ✓ replays a completed terminal job without provider or billing work (4 ms) PASS src/__tests__/unit/routes/jobsStructuredValidation.test.ts async job request validation ✓ accepts content-only legacy requests (2 ms) ✓ accepts core and generic structured fields (1 ms) ✓ accepts content-only payload emitted when PHP has no ACF fields (2 ms) ✓ rejects reserved collisions and aggregate overflow (6 ms) ✓ accepts raw HTML markup above the character limit when visible aggregate fits (6 ms) ✓ accepts the exact segmented Site Content contract (1 ms) ✓ rejects segmented Site Content with unknown field (1 ms) ✓ rejects segmented Site Content with missing contract version (1 ms) ✓ rejects segmented Site Content with wrong contract version ✓ rejects segmented Site Content with post fields mixed into segments (1 ms) ✓ rejects segmented Site Content with missing callback (1 ms) ✓ rejects segmented Site Content with missing attempt token (1 ms) ✓ rejects segmented Site Content with wrong segment shape ✓ preserves bulk-string client identity for exact pending retries (1 ms) ✓ atomically creates and queues one job for concurrent identical bulk requests (1 ms) ✓ keeps a committed job durable when immediate dispatch fails (2 ms) PASS src/__tests__/integration/routes/health.test.ts Health Routes GET /health ✓ should return healthy status (18 ms) ✓ should have valid timestamp format (2 ms) GET /health/ready ✓ should return ready when all services are healthy (3 ms) ✓ should return 503 when database is unhealthy (3 ms) ✓ should return 503 when Redis is unhealthy (3 ms) ✓ should return 503 when both services are unhealthy (3 ms) GET /health/live ✓ should return alive status (4 ms) ✓ should include process uptime (2 ms) ✓ should include memory usage (3 ms) ✓ should always return 200 even if other services are down (3 ms) Health endpoint consistency ✓ should have consistent timestamp format across all endpoints (5 ms) ✓ should respond quickly (< 1 second) (3 ms) PASS src/__tests__/unit/services/siteContentTranslation.test.ts segmented Site Content translation ✓ validates and round-trips the exact retry payload (2 ms) ✓ rejects unknown request field (13 ms) ✓ rejects missing contract version (1 ms) ✓ rejects wrong contract version (1 ms) ✓ rejects wrong resource type (1 ms) ✓ rejects non-string language ✓ rejects invalid source revision (1 ms) ✓ rejects invalid attempt token ✓ rejects empty segments ✓ rejects duplicate IDs (1 ms) ✓ rejects unknown segment field ✓ rejects non-object context ✓ rejects empty text (1 ms) ✓ enforces segment, character, payload, and context-depth bounds (7 ms) ✓ translates text only and returns every input ID in source order with unchanged context (1 ms) ✓ separates callback authority from polling metadata and advertises bounded capability (1 ms) ✓ rejects malformed stored encoding and invalid provider metrics (1 ms) ✓ rejects provider output with missing key (1 ms) ✓ rejects provider output with extra key ✓ rejects provider output with non-string value (1 ms) ✓ rejects provider output with empty translation PASS src/__tests__/unit/workerHeartbeat.test.ts WorkerHeartbeat ✓ writes a short-TTL heartbeat only after event-loop, PostgreSQL, and Redis checks succeed (2 ms) ✓ does not refresh the heartbeat when PostgreSQL fails (9 ms) ✓ does not refresh the heartbeat when Redis fails (2 ms) ✓ does not refresh the heartbeat until configuration Redis clients are ready (3 ms) ✓ does not refresh the heartbeat when Bull is not ready (2 ms) ✓ uses WORKER_ID when no container hostname is inherited (1 ms) ✓ removes only its own heartbeat during two-worker shutdown (1 ms) ✓ removes the heartbeat and closes Redis on shutdown PASS src/__tests__/unit/utils/tokenCalculation.test.ts Token Calculation Utils estimateTokens ✓ should estimate tokens for short content (1 ms) ✓ should estimate tokens for medium content (1 ms) ✓ should estimate tokens for long content ✓ should handle empty content ✓ should accept source and target language parameters (1 ms) calculateCost ✓ calculates Gemini 3.1 Flash-Lite input and output token costs independently ✓ uses the Gemini 2.5 Flash provider rates for fallback requests ✓ does not silently apply customer pricing to an unknown provider model (6 ms) ✓ handles zero tokens getCreditAllocationForTier ✓ should return correct allocation for starter tier ✓ should return correct allocation for professional tier ✓ should return correct allocation for enterprise tier estimateProcessingTime ✓ should estimate processing time from token count ✓ should be deterministic for the same content (1 ms) ✓ should include cold start overhead ✓ should increase with content length formatTokenCount ✓ should format small numbers without suffix (1 ms) ✓ should format thousands with K suffix ✓ should format millions with M suffix ✓ should round to 1 decimal place formatCost ✓ should format very small costs with 4 decimal places ✓ should format small costs with 3 decimal places (1 ms) ✓ should format regular costs with 2 decimal places ✓ should handle zero cost ✓ should handle large costs (1 ms) PASS src/__tests__/unit/geminiTruncationRetry.test.ts Gemini bulk truncation retries ✓ passes a complete response through without retrying (3 ms) ✓ retries malformed JSON as incomplete when Gemini omits a finish reason (1 ms) ✓ retries a missing id once and merges results in input order (1 ms) ✓ treats an empty translation as incomplete and retries it ✓ keeps earlier successes and returns explicit failures after persistent truncation (1 ms) ✓ splits the remaining strings after a no-progress retry round (1 ms) PASS src/__tests__/unit/services/mockTranslationProvider.test.ts MockTranslationProvider ✓ selects live and mock providers, with a fail-closed kill switch (10 ms) ✓ returns stable marked output while preserving markup, placeholders, tokens, IDs, and order (2 ms) ✓ implements all eight scenarios without sleeping for timeout (2 ms) ✓ requires persisted context for non-success async scenarios and validates UUIDs (6 ms) PASS src/__tests__/unit/routes/jobsBulkContent.test.ts bulk-content job request validation ✓ accepts a valid multi-item request where each item is a (post, language) pair (1 ms) ✓ rejects an item naming the offending ref when it has no translatable field (2 ms) ✓ rejects an item naming the offending ref when it exceeds the character cap (4 ms) ✓ rejects more than the max item count (1 ms) submitBulkContentJob ✓ creates and drains a new job on the happy path (2 ms) ✓ returns the existing pending job on a dedupe hit instead of creating a new one (3 ms) ✓ keeps a committed job durable when immediate dispatch fails (3 ms) PASS src/__tests__/unit/services/translationProvider.test.ts translation provider boundary ✓ accepts a valid text result ✓ rejects a result with inconsistent token accounting as malformed_response (9 ms) ✓ rejects structured output missing a requested field (1 ms) ✓ rejects bulk output whose ids are not in input order (1 ms) ✓ returns the validated result for each provider shape (1 ms) ✓ rejects invalid token, model, and processing metadata (2 ms) ✓ rejects structured fields that are absent, extra, or not strings (1 ms) ✓ rejects bulk output with missing items or invalid item shapes (1 ms) ✓ supports typed context validation ✓ exposes only safe typed provider error details (1 ms) PASS src/__tests__/unit/services/geminiStructured.test.ts generic structured Gemini translation ✓ translates arbitrary fields in canonical key order and restores HTML (2 ms) ✓ placeholders Gutenberg block comments so their JSON never reaches the model (1 ms) ✓ preserves source text that matches an internal placeholder (1 ms) ✓ rejects dropped HTML placeholder output (15 ms) ✓ rejects duplicated HTML placeholder output (1 ms) ✓ rejects unknown HTML placeholder output (1 ms) ✓ does not log malformed provider output (1 ms) ✓ rejects missing key output ✓ rejects extra key output ✓ rejects non-string value output (1 ms) PASS src/__tests__/unit/routes/adminLicenses.test.ts mock license issuance policy ✓ allows live issuance without mock-only requirements (1 ms) ✓ requires an admin role (2 ms) ✓ requires an explicit international owner (2 ms) ✓ requires an existing owner record (2 ms) ✓ requires an active owner and international subscription (2 ms) ✓ allows an active international subscription owner (2 ms) PASS src/__tests__/unit/workerLifecycle.test.ts startWorkerRuntime ✓ starts heartbeat only after config fallback settles and Bull is ready (2 ms) ✓ does not emit heartbeat when Bull readiness fails (5 ms) shutdownWorkerRuntime ✓ stops health reporting without disconnecting Prisma when Bull misses its drain deadline (1 ms) ✓ drains Bull before stopping heartbeat and disconnects Prisma only after heartbeat settles (2 ms) PASS src/__tests__/unit/translationServiceBatching.test.ts TranslationService bulk batching ✓ packs count-capped batches, merges all results, and preserves input order (9 ms) ✓ uses one Gemini call for a small request (2 ms) PASS src/__tests__/unit/services/exceptionService.test.ts exceptionService.normalizeRules ✓ accepts a well-formed client rule list and defaults match_type (1 ms) ✓ drops malformed entries instead of failing the request (1 ms) contains matching ✓ protects the whole word a match lands inside (2 ms) ✓ protects words that only contain the text mid-word ✓ protects the whole word around non-ASCII scripts (3 ms) ✓ stops at HTML tag boundaries in markup content (1 ms) ✓ does not swallow placeholders inserted by an earlier rule (2 ms) exception placeholder collision handling ✓ skips placeholder tokens already present in source text ✓ restores the original casing of every replaced occurrence ✓ leaves text untouched when the client sends no rules PASS src/__tests__/unit/services/mockTranslationStore.test.ts MockTranslationStore ✓ uses validated job-scoped keys, atomic counters, and 24-hour TTL (8 ms) ✓ persists release so a missed pub/sub message cannot deadlock a waiter (1 ms) ✓ wakes active waiters and supports abort and reset (1 ms) PASS src/__tests__/unit/middleware/licenseAuth.test.ts authenticateApiKey license credentials ✓ authenticates an active license for its exact plugin and activated site (3 ms) ✓ rejects missing plugin (2 ms) ✓ rejects missing site (2 ms) ✓ rejects wrong plugin (1 ms) ✓ rejects wrong site (2 ms) ✓ rejects missing owner (2 ms) ✓ rejects expired (2 ms) PASS src/__tests__/unit/utils/r2Presigner.test.ts presignGetObjectUrl ✓ matches the published AWS SigV4 query-string example (1 ms) ✓ canonicalizes exactly as AWS documents for that example (1 ms) ✓ derives the documented signature from that canonical request ✓ signs a bucket-scoped R2 object key without leaking credentials ✓ produces a different signature for a different object key (1 ms) PASS src/__tests__/unit/healthcheck.test.ts API healthcheck ✓ uses readiness and fails when dependencies are unavailable (95 ms) worker healthcheck ✓ derives an instance-specific key from HOSTNAME ✓ uses WORKER_ID when healthcheck execution has no HOSTNAME (1 ms) ✓ rejects absent, malformed, and stale heartbeats (1 ms) ✓ accepts a recent heartbeat PASS src/__tests__/unit/batchPlanner.test.ts planBatches ✓ returns no batches for empty input (1 ms) ✓ keeps a string that exceeds maxChars as its own batch ✓ packs mixed sizes greedily in order ✓ allows a string that exactly fills maxChars (1 ms) ✓ starts a new batch at the maxCount boundary ✓ starts a new batch before the JSON payload exceeds maxPayloadBytes (1 ms) ✓ preserves order and retains every input string (1 ms) PASS src/__tests__/unit/middleware/payloadTransformSiteContent.test.ts WordPress segmented Site Content payload transform ✓ maps the canonical snake-case contract without losing correlation fields (1 ms) ✓ keeps unknown and conflicting fields visible so strict validation rejects them (4 ms) PASS src/__tests__/unit/utils/structuredFields.test.ts structured async field contract ✓ canonicalizes keys and counts every field (1 ms) ✓ counts visible Unicode characters and ignores quoted HTML attributes (1 ms) ✓ matches the PHP character-count fixtures exactly ✓ accepts HTML-rich values when sanitized aggregate stays within the limit (4 ms) ✓ rejects reserved custom keys and aggregate overflow (7 ms) ✓ round-trips marked structured payloads without classifying legacy JSON ✓ splits core aliases from translated custom fields (1 ms) PASS src/__tests__/unit/services/multilingualLicenseService.test.ts multilingual license execution mode ✓ defaults newly created licenses to live mode (2 ms) ✓ persists explicitly requested mock mode (2 ms) license lifecycle mode immutability ✓ does not write mode during status, limit, expiry, or key updates (2 ms) PASS src/__tests__/unit/executionModeSchema.test.ts translation execution mode schema contract ✓ defines execution modes and mock scenarios (1 ms) ✓ keeps license and job execution indexes and live defaults (1 ms) ✓ uses an additive migration without backfill or destructive SQL (1 ms) PASS src/__tests__/unit/services/geminiTranslationProvider.test.ts Gemini translation provider adapter ✓ returns validated text output from the Gemini client (2 ms) ✓ normalizes authentication failures to safe permanent errors (1 ms) ✓ rejects Gemini bulk parse-failure sentinel before persistence PASS src/__tests__/unit/services/webhookServiceBulk.test.ts bulk webhook delivery contract ✓ uses WordPress-compatible timestamped HMAC and stable replay identity (4 ms) PASS src/__tests__/integration/routes/multilingualLicenseStatus.test.ts POST international license status ✓ validates credentials from the JSON body (18 ms) ✓ rejects missing JSON credentials (6 ms) ✓ maps an unknown license to the licensing error contract (6 ms) PASS __tests__/unit/webhook-outbox-migration.test.ts webhook outbox migration ✓ creates the schema-backed outbox table with delivery constraints (3 ms) PASS src/__tests__/unit/middleware/rateLimiter.test.ts tier rate limiting ✓ resolves the authoritative tier limit within the authenticated plugin (1 ms) ✓ shares one plugin-scoped lookup between unlimited bypass and rate enforcement ✓ bypasses an enterprise tier only when its resolved limit is exactly zero PASS src/__tests__/unit/runtimeConfiguration.test.ts runtime queue configuration ✓ /home/user/builds/backend-lazy-batch-dba05b95006f/press-zone-backend/api/docker-compose.yml preserves durable Bull keys with noeviction (1 ms) ✓ /home/user/builds/backend-lazy-batch-dba05b95006f/press-zone-backend/podman-compose.yml preserves durable Bull keys with noeviction (1 ms) ✓ preserves provider cost precision below one ten-thousandth of a dollar ✓ keeps the published Redis port separate from the internal service port PASS src/__tests__/unit/services/geminiThinkingTokens.test.ts Gemini thinking token accounting ✓ includes Gemini thinking tokens in billable output and total tokens (1 ms) PASS src/__tests__/unit/services/tierService.test.ts tierService plugin scoping ✓ resolves rate limits, credits, and PayPal plans within the requested plugin (1 ms) PASS src/__tests__/unit/routes/healthRedisCleanup.test.ts readiness Redis cleanup ✓ disconnects the request-scoped client after a successful ping (5 ms) ✓ always disconnects the request-scoped client when ping fails (3 ms) PASS src/__tests__/unit/workerLock.test.ts lockProcessingJob ✓ casts parameterized job and lease IDs to UUID before locking (1 ms) PASS src/__tests__/unit/config/paypalValidation.test.ts validatePayPalConfig ✓ accepts resolved database-backed credentials when environment credentials are absent (1 ms) ✓ reports incomplete resolved credentials without throwing PASS src/__tests__/unit/services/pluginUpdateVersions.test.ts compareVersions ✓ orders by numeric component, not lexically (1 ms) ✓ treats missing trailing components as zero (1 ms) ✓ treats unparseable components as zero rather than NaN Test Suites: 55 passed, 55 total Tests: 687 passed, 687 total Snapshots: 0 total Time: 29.244 s Ran all test suites.