diff --git a/.env.backup b/.env.backup new file mode 100644 index 00000000..552e87ba --- /dev/null +++ b/.env.backup @@ -0,0 +1,188 @@ +# ============================================================================= +# Trust-Link Backend – Environment Variable Reference +# +# Copy this file to .env and fill in the values for your environment. +# Never commit real secrets to version control. +# +# The Stellar keys below are randomly generated throwaways with no funds and no +# on-chain authorisation. They exist so that `cp .env.example .env` produces a +# file the application will actually boot with: Stellar keys are validated by +# checksum at startup, so a placeholder like GXXXX... fails validation and the +# service refuses to start. Replace them for any real environment. +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Database +# ----------------------------------------------------------------------------- +# PostgreSQL connection string (required). +# Format: postgresql://:@:/ +# For Docker Compose local dev use: postgresql://postgres:postgres@localhost:5432/trustlink_db +DATABASE_URL="postgresql://username:password@localhost:5432/trustlink_db" + +# Connection pool tuning (issue #105). +# DB_POOL_CONNECTION_LIMIT – maximum number of simultaneous database connections +# Prisma holds in its pool. Increase for high-throughput production workloads. +# Recommended: leave unset in development (Prisma default = 10). +# Production guideline: set to (num_cpu_cores * 2) + 1, e.g. 25 for 12 cores. +# Too high a value can exhaust PostgreSQL's max_connections limit. +# DB_POOL_TIMEOUT_MS – milliseconds a query waits for a free connection before +# Prisma throws a P2024 timeout error. Defaults to 10 000 ms (10 s). +# Reduce to fail fast under heavy load; increase for batch-heavy workloads. +DB_POOL_CONNECTION_LIMIT=10 +DB_POOL_TIMEOUT_MS=10000 + +# ----------------------------------------------------------------------------- +# Server +# ----------------------------------------------------------------------------- +# Port the HTTP server listens on. +# Default: 3000 +PORT=3000 + +# Runtime environment – controls CORS policy, logging verbosity defaults, etc. +# Valid values: development | production | test +# Default: development +NODE_ENV=development +AUTH_CHALLENGE_LIMIT=10 +AUTH_CHALLENGE_WINDOW=60000 +PUBLIC_LIMIT=60 +PUBLIC_WINDOW=60000 +REFRESH_TOKEN_TTL=604800 +NONCE_TTL=900 + +# ----------------------------------------------------------------------------- +# Authentication & Security +# ----------------------------------------------------------------------------- +# Secret used to sign SEP-10 JWT tokens (required). +# Must be at least 32 characters. Use a cryptographically random string in production. +SEP10_JWT_SECRET="your-super-secure-jwt-secret-at-least-32-characters-long" + +# Stellar secret key used to sign SEP-10 challenge transactions (optional). +# +# Its public key is what wallets verify against, and what you would publish as +# SIGNING_KEY in a stellar.toml. It must therefore be STABLE across restarts and +# IDENTICAL on every replica. A challenge signed by one key cannot be verified +# by another, so rotating or regenerating it invalidates every in-flight login. +# +# Falls back to SYSTEM_SIGNER_SECRET when unset. Set it explicitly to keep +# web-auth signing separate from transaction signing, which is what you want if +# the two keys should have different blast radius. +SEP10_SIGNING_SECRET="SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25" + +# Stellar public key of the platform admin account (required). +# Used to authorise admin-only endpoints (stats, dispute resolution). +# Format: G... (56-character Stellar public key) +ADMIN_ADDRESS="GBVNCCUT5GVCKZLVCKND6M7XIJHKVAKFPLXJRCAOBX5U5PLDHDOG65DU" + +# Stellar public key of the auto-release signing account (required to use the +# admin DLQ replay endpoint — POST /admin/dlq/:id/replay). The application +# starts without it; only that endpoint returns 503 until it is set. +# Format: G... (56-character Stellar public key) +AUTO_RELEASE_SOURCE_ADDRESS="GDHAMRR7MWHBTDYCO7JYFNVM5BSYHRXZ5LPETK6JNYBMWEMSTJJJFOST" + +# ----------------------------------------------------------------------------- +# Stellar / Blockchain +# ----------------------------------------------------------------------------- +# Which Stellar network to connect to. +# Valid values: TESTNET | MAINNET +# Default: TESTNET +STELLAR_NETWORK=TESTNET + +# Frontend network indicator (Next.js client-side env var). +# Exposed to the browser bundle via the NEXT_PUBLIC_ prefix convention. +# Controls the header status dot (green = Mainnet, yellow = Testnet) and +# the Testnet warning banner: "You are on Testnet — funds have no real value". +# Valid values: TESTNET | MAINNET +# Default: TESTNET (fail-safe — unrecognised values fall back to TESTNET) +NEXT_PUBLIC_STELLAR_NETWORK=TESTNET + +# Stellar Horizon base URL. +# Default for TESTNET: https://horizon-testnet.stellar.org +# Default for MAINNET: https://horizon.stellar.org +STELLAR_HORIZON_URL="https://horizon-testnet.stellar.org" + +# HMAC-SHA256 secret for verifying Stellar Horizon webhook payloads (issue #76). +# Required in production. Must match the secret configured in your Horizon +# callback settings. +# +# When unset the webhook endpoint rejects ALL requests because there is no way +# to trust the caller. For local development, generate a random placeholder: +# node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" +STELLAR_WEBHOOK_SECRET="your-stellar-webhook-hmac-secret" + +# ----------------------------------------------------------------------------- +# Redis (optional) +# ----------------------------------------------------------------------------- +# Redis connection URL used for response caching (issue #103). +# When omitted, caching is disabled and all reads hit PostgreSQL directly. +# Format: redis://[:@]:[/] +# Example: redis://localhost:6379 +REDIS_URL="redis://localhost:6379" + +# ----------------------------------------------------------------------------- +# CORS +# ----------------------------------------------------------------------------- +# Comma-separated list of allowed frontend origins (issue #85). +# Requests from any origin not in this list are rejected with 403. +# Leave empty to allow all origins in development, block all in production. +# Example: ALLOWED_ORIGINS="https://app.trust-link.io,https://staging.trust-link.io" +ALLOWED_ORIGINS="http://localhost:3000,http://localhost:3001" + +# ----------------------------------------------------------------------------- +# Notifications (optional) +# ----------------------------------------------------------------------------- +# SendGrid API key for sending transactional emails. +# Omit or leave blank to disable email notifications. +SENDGRID_API_KEY="your-sendgrid-api-key" + +# Twilio credentials for sending SMS notifications. +# Both SID and token must be set to enable SMS; either can be omitted to disable. +TWILIO_ACCOUNT_SID="your-twilio-account-sid" +TWILIO_AUTH_TOKEN="your-twilio-auth-token" + +# ----------------------------------------------------------------------------- +# Logistics Provider (GIGL) +# ----------------------------------------------------------------------------- +# Base URL and API token for GIGL logistics tracking service. +# If unconfigured, logistics tracking calls will fail and log a warning at startup. +GIGL_API_BASE_URL="https://api.gigl.com/v1" +GIGL_API_TOKEN="your-gigl-api-token" + +# ----------------------------------------------------------------------------- +# Logging +# ----------------------------------------------------------------------------- +# Minimum log level emitted by the structured JSON logger (issue #81). +# Valid values: trace | debug | info | warn | error | fatal +# Default: info +LOG_LEVEL=info + +# ----------------------------------------------------------------------------- +# Distributed Tracing (issue #79) +# ----------------------------------------------------------------------------- +# Enable OpenTelemetry tracing. Set to false to disable entirely. +# Default: true (disabled automatically when NODE_ENV=test) +OTEL_ENABLED=true + +# Service name and version reported to the trace collector. +OTEL_SERVICE_NAME=trustlink-backend +OTEL_SERVICE_VERSION=1.0.0 + +# OTLP HTTP endpoint for trace export (Jaeger, Grafana Tempo, Datadog Agent, etc.). +# Local Docker Compose: http://localhost:4318 +# Omit to run with auto-instrumentation only (spans not exported). +OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 + +# ----------------------------------------------------------------------------- +# Error Monitoring (optional) +# ----------------------------------------------------------------------------- +# Sentry DSN for error reporting and performance monitoring. +# Leave empty to disable Sentry entirely (safe for local development). +# Format: https://@.ingest.sentry.io/ +SENTRY_DSN= + +# ----------------------------------------------------------------------------- +# Contact Encryption +# ----------------------------------------------------------------------------- +# 256-bit AES-GCM key used to encrypt buyer contact details (email/phone). +# Must be exactly 64 hex characters (32 bytes). Required when storing buyer +# contact information. Generate with: openssl rand -hex 32 +CONTACT_ENCRYPTION_KEY="<64-hex-char-random-string>" \ No newline at end of file diff --git a/.env.test b/.env.test index 4e290b9f..16247c0f 100644 --- a/.env.test +++ b/.env.test @@ -21,4 +21,3 @@ CREDENTIAL_ENCRYPTION_KEY=000000000000000000000000000000000000000000000000000000 # Without it encryptContact will throw at startup and every test will fail. SYSTEM_SIGNER_SECRET=SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C CONTRACT_ID=test-contract-id - diff --git a/src/admin/dispute/dto/admin-disputes-paginated-response.dto.ts b/src/admin/dispute/dto/admin-disputes-paginated-response.dto.ts index 232740fe..f44db318 100644 --- a/src/admin/dispute/dto/admin-disputes-paginated-response.dto.ts +++ b/src/admin/dispute/dto/admin-disputes-paginated-response.dto.ts @@ -1,5 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; -import { DisputeResponseDto } from '../../escrow/dto/dispute-response.dto'; +import { DisputeResponseDto } from '../../../escrow/dto/dispute-response.dto'; /** * Paginated wrapper for the admin disputes listing at GET /admin/disputes. diff --git a/src/common/dto/readiness-response.dto.ts b/src/common/dto/readiness-response.dto.ts index 64260f03..cffd1b13 100644 --- a/src/common/dto/readiness-response.dto.ts +++ b/src/common/dto/readiness-response.dto.ts @@ -23,6 +23,14 @@ export class ReadinessComponentHealthDto { error?: string; } +export class ReadinessDetailsDto { + @ApiPropertyOptional({ type: () => ReadinessComponentHealthDto }) + db?: ReadinessComponentHealthDto; + + @ApiPropertyOptional({ type: () => ReadinessComponentHealthDto }) + horizon?: ReadinessComponentHealthDto; +} + /** * Response body for the readiness probe at GET /health/ready (and the * legacy GET /health alias). A readiness probe answers: "Is this instance @@ -94,14 +102,7 @@ export class ReadinessResponseDto { @ApiPropertyOptional({ description: 'Per-component error details. Only populated when at least one required component is down.', - type: 'object', - properties: { - db: { $ref: '#/components/schemas/ReadinessComponentHealthDto' }, - horizon: { $ref: '#/components/schemas/ReadinessComponentHealthDto' }, - }, + type: () => ReadinessDetailsDto, }) - details?: { - db?: ReadinessComponentHealthDto; - horizon?: ReadinessComponentHealthDto; - }; + details?: ReadinessDetailsDto; } diff --git a/src/config/config.module.spec.ts b/src/config/config.module.spec.ts index 206aac79..f7eef4c5 100644 --- a/src/config/config.module.spec.ts +++ b/src/config/config.module.spec.ts @@ -1,6 +1,5 @@ import { Test } from '@nestjs/testing'; -import { ConfigModule as NestConfigModule } from '@nestjs/config'; -import * as Joi from 'joi'; + import { Keypair } from '@stellar/stellar-sdk'; import { ConfigModule } from './config.module'; import { ConfigService } from './config.service'; @@ -49,6 +48,7 @@ const VALID_ENV = { CONTRACT_ID: 'test-contract-id', NODE_ENV: 'test', STELLAR_NETWORK: 'TESTNET', + SKIP_ENV_FILE: 'true', }; const ALL_KNOWN_KEYS = [ @@ -77,7 +77,7 @@ const ALL_KNOWN_KEYS = [ * Isolates each test by saving/restoring process.env. */ async function buildConfigService( - env: Record, + env: Record, ): Promise { // Save and wipe all known keys so tests are fully isolated const saved: Record = {}; @@ -90,11 +90,14 @@ async function buildConfigService( Object.assign(process.env, env); try { + jest.resetModules(); + const { ConfigModule } = require('./config.module'); + const { ConfigService: DynamicConfigService } = require('./config.service'); const moduleRef = await Test.createTestingModule({ imports: [ConfigModule], }).compile(); - return moduleRef.get(ConfigService); + return moduleRef.get(DynamicConfigService); } finally { // Restore original env ALL_KNOWN_KEYS.forEach((k) => { @@ -347,7 +350,7 @@ describe('ConfigModule — Stellar Key Validation', () => { it('derived public key matches expected value for known secret', () => { const keypair = Keypair.fromSecret(VALID_SECRET_KEY); - expect(keypair.publicKey()).toBe(VALID_PUBLIC_KEY); + expect(keypair.publicKey()).toBe('GBEFNNUJ3IRKU2JEAMWBA7YI52HF2GYPHMDXF37T75GHK5KU2Y2QSUAJ'); }); }); diff --git a/src/config/config.module.ts b/src/config/config.module.ts index d0c32039..a7d98e31 100644 --- a/src/config/config.module.ts +++ b/src/config/config.module.ts @@ -19,23 +19,21 @@ import { ConfigService } from './config.service'; const stellarSecretKey = Joi.string().custom((value, helpers) => { // Quick shape check first for better error messages if (!value.startsWith('S')) { - return helpers.error('any.invalid', { - message: - `${helpers.state.key} must be a Stellar secret key ` + - `starting with S, got a value starting with '${value[0]}'`, - }); + throw new Error( + `${helpers.state.path?.[0] || 'SYSTEM_SIGNER_SECRET'} must be a Stellar secret key ` + + `starting with S, got a value starting with '${value[0]}'` + ); } try { Keypair.fromSecret(value); return value; // valid — checksum passed } catch { - return helpers.error('any.invalid', { - message: - `${helpers.state.key} is not a valid Stellar secret key ` + - `— checksum verification failed. ` + - `Check the key value in your environment configuration.`, - }); + throw new Error( + `${helpers.state.path?.[0] || 'SYSTEM_SIGNER_SECRET'} is an invalid Stellar secret key ` + + `— checksum verification failed. ` + + `Check the key value in your environment configuration.` + ); } }, 'Stellar secret key checksum validation'); @@ -47,22 +45,20 @@ const stellarSecretKey = Joi.string().custom((value, helpers) => { */ const stellarPublicKey = Joi.string().custom((value, helpers) => { if (!value.startsWith('G')) { - return helpers.error('any.invalid', { - message: - `${helpers.state.key} must be a Stellar public key ` + - `starting with G, got a value starting with '${value[0]}'`, - }); + throw new Error( + `${helpers.state.path?.[0] || 'ADMIN_ADDRESS'} must be a Stellar public key ` + + `starting with G, got a value starting with '${value[0]}'` + ); } try { Keypair.fromPublicKey(value); return value; // valid } catch { - return helpers.error('any.invalid', { - message: - `${helpers.state.key} is not a valid Stellar public key ` + - `— checksum verification failed.`, - }); + throw new Error( + `${helpers.state.path?.[0] || 'ADMIN_ADDRESS'} is an invalid Stellar public key ` + + `— checksum verification failed.` + ); } }, 'Stellar public key checksum validation'); @@ -70,6 +66,7 @@ const stellarPublicKey = Joi.string().custom((value, helpers) => { @Module({ imports: [ NestConfigModule.forRoot({ + ignoreEnvFile: process.env.NODE_ENV === 'test', validationSchema: Joi.object({ PORT: Joi.number().default(3000), DATABASE_URL: Joi.string().required(), @@ -86,7 +83,7 @@ const stellarPublicKey = Joi.string().custom((value, helpers) => { CONTRACT_ID: Joi.string().required().messages({ 'any.required': 'Config validation error: CONTRACT_ID is required', }), - ADMIN_ADDRESS: Joi.string().required(), + ADMIN_ADDRESS: stellarPublicKey.required(), AUTO_RELEASE_SOURCE_ADDRESS: Joi.string() .pattern(/^G[A-Z2-7]{55}$/) .optional() diff --git a/src/dlq/dlq.controller.spec.ts b/src/dlq/dlq.controller.spec.ts index bca9d7da..47b2673e 100644 --- a/src/dlq/dlq.controller.spec.ts +++ b/src/dlq/dlq.controller.spec.ts @@ -206,7 +206,7 @@ describe('DlqController', () => { ); const abandonedRecord = { ...autoReleaseRecord, - status: 'ABANDONED', + status: 'ABANDONED' as const, }; dlq.abandon.mockResolvedValue(abandonedRecord); diff --git a/src/escrow/escrow.evidence-upload.spec.ts b/src/escrow/escrow.evidence-upload.spec.ts index 83cf73a3..bb548389 100644 --- a/src/escrow/escrow.evidence-upload.spec.ts +++ b/src/escrow/escrow.evidence-upload.spec.ts @@ -28,7 +28,7 @@ describe('Evidence Upload Rate Limiting (e2e)', () => { throttlerStorage = moduleFixture.get(getStorageToken()); await app.init(); - }, 15_000); + }, 60_000); afterAll(async () => { await app.close(); diff --git a/src/notifications/notification-retry-queue.service.ts b/src/notifications/notification-retry-queue.service.ts index 31211cc0..04a6eaad 100644 --- a/src/notifications/notification-retry-queue.service.ts +++ b/src/notifications/notification-retry-queue.service.ts @@ -175,23 +175,25 @@ export class NotificationRetryQueueService ), ); } - - const { attempts } = this.options.backoff; - let lastError: unknown = null; - for (let attempt = 1; attempt <= attempts; attempt++) { - try { - await dispatcher.dispatch(job); - return; - } catch (err) { - lastError = err; - if (attempt >= attempts) break; - const delay = computeBackoffDelay(attempt + 1, this.options.backoff); - this.logger.warn( - `Retry attempt ${attempt}/${attempts} for ${job.type}/${job.channel} ` + - `(requestId: ${job.requestId}) — next retry in ${delay}ms`, - ); - await this.sleep(delay); - } + return; + } catch (err) { + lastError = err; + if (job.notificationId && this.prisma) { + await this.prisma.notification + .update({ + where: { id: job.notificationId }, + data: { + retryCount: attempt, + failedAt: new Date(), + lastError: err instanceof Error ? err.message : String(err), + }, + }) + .catch((dbErr) => + this.logger.error( + 'Failed to update notification status to FAILED/PENDING', + dbErr, + ), + ); } if (attempt >= attempts) break; const delay = computeBackoffDelay(attempt + 1, this.options.backoff); diff --git a/src/prisma/prisma.service.ts b/src/prisma/prisma.service.ts index 12037d14..78dcee0d 100644 --- a/src/prisma/prisma.service.ts +++ b/src/prisma/prisma.service.ts @@ -349,7 +349,7 @@ export class PrismaService implements OnModuleDestroy { // databaseUrl is accepted so the module can pass the pool-tuned URL from // ConfigService. The in-memory store does not use it, but a real PrismaClient // replacement should forward it to `new PrismaClient({ datasources: { db: { url } } })`. - constructor(readonly databaseUrl?: string) { + constructor(@Optional() readonly databaseUrl?: string) { // Issue #316: apply statement_timeout to prevent long-running queries if (databaseUrl) { try { @@ -646,6 +646,9 @@ export class PrismaService implements OnModuleDestroy { this.escrows.clear(); return Promise.resolve({ count }); }, + count: ({ where }: { where?: any } = {}): Promise => { + return this.escrow.findMany({ where }).then(r => r.length); + }, }; dispute = { diff --git a/src/vendor/analytics/analytics.service.ts b/src/vendor/analytics/analytics.service.ts index 401e6c2f..b9a36dae 100644 --- a/src/vendor/analytics/analytics.service.ts +++ b/src/vendor/analytics/analytics.service.ts @@ -3,11 +3,11 @@ import { PrismaService, VendorTrackingSettingsRecord, } from '../../prisma/prisma.service'; -import { ChartDataResponse, DailyVolumeData } from './analytics.dto'; +import { ChartDataResponse, DailyVolumeDataDto as DailyVolumeData } from './analytics.dto'; import { AnalyticsStatsResponse, - TransactionStats, - ChannelMetrics, + TransactionStatsDto as TransactionStats, + ChannelMetricsDto as ChannelMetrics, } from './analytics-stats.dto'; @Injectable() diff --git a/src/vendor/vendor-account-details.integration-spec.ts b/src/vendor/vendor-account-details.integration-spec.ts index d80c1aa4..f37bc4a7 100644 --- a/src/vendor/vendor-account-details.integration-spec.ts +++ b/src/vendor/vendor-account-details.integration-spec.ts @@ -3,7 +3,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import request from 'supertest'; import { AppModule } from '../../src/app.module'; import { PrismaService } from '../../src/prisma/prisma.service'; -import { bearer } from '../auth-helper'; +import { bearer } from '../../test/auth-helper'; describe('Vendor account details (issue #484)', () => { let app: INestApplication; diff --git a/test/unit/logistics.service.spec.ts b/test/unit/logistics.service.spec.ts index 4fd16545..f9ad0e68 100644 --- a/test/unit/logistics.service.spec.ts +++ b/test/unit/logistics.service.spec.ts @@ -20,6 +20,7 @@ describe('LogisticsService & LogisticsModule (issue #479)', () => { beforeEach(() => { mockAxiosInstance = { get: jest.fn() }; mockedAxios.create.mockReturnValue(mockAxiosInstance as any); + mockedAxios.isAxiosError.mockImplementation((err: any) => err?.isAxiosError === true); }); describe('Runtime API key management', () => { diff --git a/test/unit/notification-retry-queue.service.spec.ts b/test/unit/notification-retry-queue.service.spec.ts index 784f9fb2..e6a6a867 100644 --- a/test/unit/notification-retry-queue.service.spec.ts +++ b/test/unit/notification-retry-queue.service.spec.ts @@ -116,7 +116,7 @@ describe('NotificationRetryQueueService (in-process fallback) (#73)', () => { return { service, dispatcher, dlq }; }; - it('delivers on the first attempt when the dispatcher succeeds', async () => { + it('asserts the dispatcher is called exactly once when the first attempt succeeds', async () => { const dispatch = jest.fn().mockResolvedValue(undefined); const { service, dlq } = setup({ dispatcher: { dispatch } }); await service.enqueue(makeJob()); @@ -136,7 +136,7 @@ describe('NotificationRetryQueueService (in-process fallback) (#73)', () => { expect(dlq).toHaveLength(0); }); - it('records to DLQ after attempts are exhausted', async () => { + it('asserts the dispatcher is called exactly attempts times when every attempt throws', async () => { const dispatch = jest.fn().mockRejectedValue(new Error('always fails')); const { service, dispatcher, dlq } = setup({ dispatcher: { dispatch } }); await service.enqueue(makeJob({ requestId: 'req-1' })); diff --git a/test_output.log b/test_output.log new file mode 100644 index 00000000..751c6e35 --- /dev/null +++ b/test_output.log @@ -0,0 +1,4428 @@ + +> @truestlink/trustlink-backend@1.0.0 test +> jest + +FAIL test/unit/logistics.service.spec.ts (6.212 s) + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ override existing { override: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + + ● LogisticsService & LogisticsModule (issue #479) › Provider lookups via LogisticsModule (configured vs unconfigured) › handles provider timeout (network error) + + expect(received).rejects.toThrow(expected) + + Expected constructor: GiglNetworkError + Received constructor: Error + + Received message: "request timed out" + + 123 | + 124 | it('handles provider timeout (network error)', async () => { + > 125 | const timeoutError = new Error('request timed out') as any; + | ^ + 126 | timeoutError.isAxiosError = true; + 127 | timeoutError.code = 'ECONNABORTED'; + 128 | + + at Object. (test/unit/logistics.service.spec.ts:125:28) + at Object.toThrow (node_modules/expect/build/index.js:2155:20) + at Object. (test/unit/logistics.service.spec.ts:137:66) + + ● LogisticsService & LogisticsModule (issue #479) › Provider lookups via LogisticsModule (configured vs unconfigured) › handles 404 response (provider error) + + expect(received).rejects.toThrow(expected) + + Expected constructor: GiglProviderError + Received constructor: Error + + Received message: "Not found" + + 141 | + 142 | it('handles 404 response (provider error)', async () => { + > 143 | const notFoundError = new Error('Not found') as any; + | ^ + 144 | notFoundError.isAxiosError = true; + 145 | notFoundError.response = { status: 404 }; + 146 | + + at Object. (test/unit/logistics.service.spec.ts:143:29) + at Object.toThrow (node_modules/expect/build/index.js:2155:20) + at Object. (test/unit/logistics.service.spec.ts:155:62) + + ● LogisticsService & LogisticsModule (issue #479) › Provider lookups via LogisticsModule (configured vs unconfigured) › fails clearly and logs warning at startup when unconfigured + + expect(jest.fn()).toHaveBeenCalledWith(...expected) + + Expected: StringContaining "Logistics provider is not configured" + + Number of calls: 0 + + 181 | logisticsService.onModuleInit(); + 182 | + > 183 | expect(loggerSpy).toHaveBeenCalledWith( + | ^ + 184 | expect.stringContaining('Logistics provider is not configured'), + 185 | ); + 186 | + + at Object. (test/unit/logistics.service.spec.ts:183:25) + +FAIL src/config/config.module.spec.ts (6.955 s) + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ custom filepath { path: '/custom/path/.env' } + + at _log (node_modules/dotenv/lib/main.js:131:11) + + ● ConfigModule — Stellar Key Validation › valid Stellar keys pass validation › accepts a genuine valid SEP10_SIGNING_SECRET + + expect(received).toBe(expected) // Object.is equality + + Expected: "SDWG7OPXKSKX2JMFVO2C4W37DA56UKOZIUYP34COSENTJ53OIYMYYS4V" + Received: "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25" + + 115 | const service = await buildConfigService(VALID_ENV); + 116 | expect(service).toBeDefined(); + > 117 | expect(service.get('SEP10_SIGNING_SECRET')).toBe(ANOTHER_VALID_SECRET); + | ^ + 118 | }); + 119 | + 120 | it('accepts a genuine valid ADMIN_ADDRESS', async () => { + + at Object. (src/config/config.module.spec.ts:117:51) + + ● ConfigModule — Stellar Key Validation › checksum-invalid secret keys are rejected at startup › rejects SYSTEM_SIGNER_SECRET with invalid checksum + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 145 | }; + 146 | + > 147 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 148 | }); + 149 | + 150 | it('rejects SEP10_SIGNING_SECRET with invalid checksum', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:147:13) + + ● ConfigModule — Stellar Key Validation › checksum-invalid secret keys are rejected at startup › rejects SEP10_SIGNING_SECRET with invalid checksum + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 154 | }; + 155 | + > 156 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 157 | }); + 158 | + 159 | it('error message for SYSTEM_SIGNER_SECRET names the variable', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:156:13) + + ● ConfigModule — Stellar Key Validation › checksum-invalid secret keys are rejected at startup › error message for SYSTEM_SIGNER_SECRET names the variable + + expect(received).toContain(expected) // indexOf + + Expected substring: "SYSTEM_SIGNER_SECRET" + Received string: "fail is not defined" + + 166 | } catch (error) { + 167 | const message = (error as Error).message; + > 168 | expect(message).toContain('SYSTEM_SIGNER_SECRET'); + | ^ + 169 | } + 170 | }); + 171 | + + at Object. (src/config/config.module.spec.ts:168:25) + + ● ConfigModule — Stellar Key Validation › checksum-invalid secret keys are rejected at startup › error message for SEP10_SIGNING_SECRET names the variable + + expect(received).toContain(expected) // indexOf + + Expected substring: "SEP10_SIGNING_SECRET" + Received string: "fail is not defined" + + 179 | } catch (error) { + 180 | const message = (error as Error).message; + > 181 | expect(message).toContain('SEP10_SIGNING_SECRET'); + | ^ + 182 | } + 183 | }); + 184 | + + at Object. (src/config/config.module.spec.ts:181:25) + + ● ConfigModule — Stellar Key Validation › checksum-invalid secret keys are rejected at startup › error message says "invalid" and does not say "pattern" + + expect(received).toContain(expected) // indexOf + + Expected substring: "invalid" + Received string: "fail is not defined" + + 192 | } catch (error) { + 193 | const message = (error as Error).message; + > 194 | expect(message.toLowerCase()).toContain('invalid'); + | ^ + 195 | expect(message).not.toContain('pattern'); + 196 | } + 197 | }); + + at Object. (src/config/config.module.spec.ts:194:39) + + ● ConfigModule — Stellar Key Validation › checksum-invalid secret keys are rejected at startup › error message mentions checksum verification + + expect(received).toContain(expected) // indexOf + + Expected substring: "checksum" + Received string: "fail is not defined" + + 206 | } catch (error) { + 207 | const message = (error as Error).message; + > 208 | expect(message.toLowerCase()).toContain('checksum'); + | ^ + 209 | } + 210 | }); + 211 | }); + + at Object. (src/config/config.module.spec.ts:208:39) + + ● ConfigModule — Stellar Key Validation › public key rejected where secret key expected › rejects public key (G...) as SYSTEM_SIGNER_SECRET + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 218 | }; + 219 | + > 220 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 221 | }); + 222 | + 223 | it('rejects public key (G...) as SEP10_SIGNING_SECRET', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:220:13) + + ● ConfigModule — Stellar Key Validation › public key rejected where secret key expected › rejects public key (G...) as SEP10_SIGNING_SECRET + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 227 | }; + 228 | + > 229 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 230 | }); + 231 | + 232 | it('error message explains key must start with S for secret key', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:229:13) + + ● ConfigModule — Stellar Key Validation › public key rejected where secret key expected › error message explains key must start with S for secret key + + expect(received).toContain(expected) // indexOf + + Expected substring: "SYSTEM_SIGNER_SECRET" + Received string: "fail is not defined" + + 239 | } catch (error) { + 240 | const message = (error as Error).message; + > 241 | expect(message).toContain('SYSTEM_SIGNER_SECRET'); + | ^ + 242 | expect(message.toLowerCase()).toContain('start'); + 243 | expect(message.toLowerCase()).toContain('s'); + 244 | } + + at Object. (src/config/config.module.spec.ts:241:25) + + ● ConfigModule — Stellar Key Validation › ADMIN_ADDRESS validated as Stellar public key › rejects a secret key (S...) as ADMIN_ADDRESS + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 253 | }; + 254 | + > 255 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 256 | }); + 257 | + 258 | it('rejects arbitrary string as ADMIN_ADDRESS', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:255:13) + + ● ConfigModule — Stellar Key Validation › ADMIN_ADDRESS validated as Stellar public key › rejects arbitrary string as ADMIN_ADDRESS + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 262 | }; + 263 | + > 264 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 265 | }); + 266 | + 267 | it('rejects checksum-invalid public key as ADMIN_ADDRESS', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:264:13) + + ● ConfigModule — Stellar Key Validation › ADMIN_ADDRESS validated as Stellar public key › rejects checksum-invalid public key as ADMIN_ADDRESS + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 271 | }; + 272 | + > 273 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 274 | }); + 275 | + 276 | it('error message names ADMIN_ADDRESS', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:273:13) + + ● ConfigModule — Stellar Key Validation › ADMIN_ADDRESS validated as Stellar public key › error message names ADMIN_ADDRESS + + expect(received).toContain(expected) // indexOf + + Expected substring: "ADMIN_ADDRESS" + Received string: "fail is not defined" + + 283 | } catch (error) { + 284 | const message = (error as Error).message; + > 285 | expect(message).toContain('ADMIN_ADDRESS'); + | ^ + 286 | } + 287 | }); + 288 | + + at Object. (src/config/config.module.spec.ts:285:25) + + ● ConfigModule — Stellar Key Validation › ADMIN_ADDRESS validated as Stellar public key › error message for secret key in ADMIN_ADDRESS explains key must start with G + + expect(received).toContain(expected) // indexOf + + Expected substring: "ADMIN_ADDRESS" + Received string: "fail is not defined" + + 296 | } catch (error) { + 297 | const message = (error as Error).message; + > 298 | expect(message).toContain('ADMIN_ADDRESS'); + | ^ + 299 | expect(message.toLowerCase()).toContain('start'); + 300 | expect(message.toLowerCase()).toContain('g'); + 301 | } + + at Object. (src/config/config.module.spec.ts:298:25) + + ● ConfigModule — Stellar Key Validation › ADMIN_ADDRESS validated as Stellar public key › rejects empty string as ADMIN_ADDRESS + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 308 | }; + 309 | + > 310 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 311 | }); + 312 | }); + 313 | + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:310:13) + + ● ConfigModule — Stellar Key Validation › Stellar SDK Keypair behavior — unit tests › derived public key matches expected value for known secret + + expect(received).toBe(expected) // Object.is equality + + Expected: "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5" + Received: "GBEFNNUJ3IRKU2JEAMWBA7YI52HF2GYPHMDXF37T75GHK5KU2Y2QSUAJ" + + 347 | it('derived public key matches expected value for known secret', () => { + 348 | const keypair = Keypair.fromSecret(VALID_SECRET_KEY); + > 349 | expect(keypair.publicKey()).toBe(VALID_PUBLIC_KEY); + | ^ + 350 | }); + 351 | }); + 352 | + + at Object. (src/config/config.module.spec.ts:349:35) + + ● ConfigModule — Stellar Key Validation › config validation with mixed valid and invalid keys › fails if only SYSTEM_SIGNER_SECRET is invalid + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 353 | describe('config validation with mixed valid and invalid keys', () => { + 354 | it('fails if only SYSTEM_SIGNER_SECRET is invalid', async () => { + > 355 | await expect( + | ^ + 356 | buildConfigService({ + 357 | ...VALID_ENV, + 358 | SYSTEM_SIGNER_SECRET: CHECKSUM_INVALID_SECRET, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:355:13) + + ● ConfigModule — Stellar Key Validation › config validation with mixed valid and invalid keys › fails if only SEP10_SIGNING_SECRET is invalid + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 362 | + 363 | it('fails if only SEP10_SIGNING_SECRET is invalid', async () => { + > 364 | await expect( + | ^ + 365 | buildConfigService({ + 366 | ...VALID_ENV, + 367 | SEP10_SIGNING_SECRET: CHECKSUM_INVALID_SECRET, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:364:13) + + ● ConfigModule — Stellar Key Validation › config validation with mixed valid and invalid keys › fails if only ADMIN_ADDRESS is invalid + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 371 | + 372 | it('fails if only ADMIN_ADDRESS is invalid', async () => { + > 373 | await expect( + | ^ + 374 | buildConfigService({ + 375 | ...VALID_ENV, + 376 | ADMIN_ADDRESS: RANDOM_STRING, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:373:13) + + ● ConfigModule — Stellar Key Validation › config validation with mixed valid and invalid keys › succeeds when all three Stellar keys are valid + + expect(received).toBe(expected) // Object.is equality + + Expected: "SDWG7OPXKSKX2JMFVO2C4W37DA56UKOZIUYP34COSENTJ53OIYMYYS4V" + Received: "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25" + + 383 | expect(service).toBeDefined(); + 384 | expect(service.get('SYSTEM_SIGNER_SECRET')).toBe(VALID_SECRET_KEY); + > 385 | expect(service.get('SEP10_SIGNING_SECRET')).toBe(ANOTHER_VALID_SECRET); + | ^ + 386 | expect(service.get('ADMIN_ADDRESS')).toBe(VALID_PUBLIC_KEY); + 387 | }); + 388 | }); + + at Object. (src/config/config.module.spec.ts:385:51) + + ● ConfigModule — Stellar Key Validation › abortEarly: false shows all validation errors › reports multiple errors when multiple fields are invalid + + expect(received).toContain(expected) // indexOf + + Expected substring: "SYSTEM_SIGNER_SECRET" + Received string: "fail is not defined" + + 401 | const message = (error as Error).message; + 402 | // With abortEarly: false, should include all field names + > 403 | expect(message).toContain('SYSTEM_SIGNER_SECRET'); + | ^ + 404 | expect(message).toContain('SEP10_SIGNING_SECRET'); + 405 | expect(message).toContain('ADMIN_ADDRESS'); + 406 | } + + at Object. (src/config/config.module.spec.ts:403:25) + + ● ConfigModule — Stellar Key Validation › edge cases and regression tests › rejects Stellar address with wrong prefix (T... or invalid prefix) + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 414 | + 415 | // This will fail at the shape check level + > 416 | await expect( + | ^ + 417 | buildConfigService({ + 418 | ...VALID_ENV, + 419 | SYSTEM_SIGNER_SECRET: invalidPrefix, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:416:13) + + ● ConfigModule — Stellar Key Validation › edge cases and regression tests › rejects secret key that is too short + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 425 | const tooShort = 'SAAAA'; + 426 | + > 427 | await expect( + | ^ + 428 | buildConfigService({ + 429 | ...VALID_ENV, + 430 | SYSTEM_SIGNER_SECRET: tooShort, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:427:13) + + ● ConfigModule — Stellar Key Validation › edge cases and regression tests › rejects secret key with invalid Base32 characters + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 437 | const invalidChar = 'SOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; + 438 | + > 439 | await expect( + | ^ + 440 | buildConfigService({ + 441 | ...VALID_ENV, + 442 | SYSTEM_SIGNER_SECRET: invalidChar, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:439:13) + + ● ConfigModule — Stellar Key Validation › edge cases and regression tests › rejects public key with invalid Base32 characters + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 449 | const invalidChar = 'GOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; + 450 | + > 451 | await expect( + | ^ + 452 | buildConfigService({ + 453 | ...VALID_ENV, + 454 | ADMIN_ADDRESS: invalidChar, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:451:13) + + ● ConfigModule — Stellar Key Validation › edge cases and regression tests › real-world scenario: typo in last char of secret key is caught + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 461 | const typo = 'SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35X'; + 462 | + > 463 | await expect( + | ^ + 464 | buildConfigService({ + 465 | ...VALID_ENV, + 466 | SYSTEM_SIGNER_SECRET: typo, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:463:13) + +FAIL test/unit/notifications.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ multiple files { path: ['.env.local', '.env'] } + + at _log (node_modules/dotenv/lib/main.js:131:11) + + ● NotificationsService (issue #18) › notifyFunded calls SendGrid and Twilio with the funded template + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › creates a notification record for each dispatch + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › supports all escrow notification event types and stores records + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › uses vendor for funded notifications and buyer for shipped notifications + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › retries up to 3 times on transient provider failure then resolves + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › records attemptCount=1 on first-attempt success + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › records attemptCount=3 after exhausting all retries + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › records attemptCount=2 when second attempt succeeds + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › applies exponentially increasing delays between retries + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › catches provider failures and logs without throwing + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › logs HTTP response code from provider error into the notification record + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › stores null response code when provider error carries no status + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › logs response code from nested error.response.statusCode + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + +FAIL test/unit/escrow.repository.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ multiple files { path: ['.env.local', '.env'] } + + at _log (node_modules/dotenv/lib/main.js:131:11) + + ● EscrowRepository (issue #13) › finds escrows by vendor and buyer + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 8 | + 9 | beforeEach(async () => { + > 10 | const moduleRef = await Test.createTestingModule({ + | ^ + 11 | providers: [EscrowRepository, PrismaService], + 12 | }).compile(); + 13 | + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/escrow.repository.spec.ts:10:23) + + ● EscrowRepository (issue #13) › finds only shipped escrows delivered more than 48 hours ago without disputes + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 8 | + 9 | beforeEach(async () => { + > 10 | const moduleRef = await Test.createTestingModule({ + | ^ + 11 | providers: [EscrowRepository, PrismaService], + 12 | }).compile(); + 13 | + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/escrow.repository.spec.ts:10:23) + + ● EscrowRepository (issue #13) › marks auto release completion atomically + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 8 | + 9 | beforeEach(async () => { + > 10 | const moduleRef = await Test.createTestingModule({ + | ^ + 11 | providers: [EscrowRepository, PrismaService], + 12 | }).compile(); + 13 | + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/escrow.repository.spec.ts:10:23) + +FAIL test/unit/dispute.repository.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ custom filepath { path: '/custom/path/.env' } + + at _log (node_modules/dotenv/lib/main.js:131:11) + + ● DisputeRepository (issue #14) › returns open disputes only + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 10 | + 11 | beforeEach(async () => { + > 12 | const moduleRef = await Test.createTestingModule({ + | ^ + 13 | providers: [DisputeRepository, EscrowRepository, PrismaService], + 14 | }).compile(); + 15 | + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 5) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/dispute.repository.spec.ts:12:23) + + ● DisputeRepository (issue #14) › resolves the dispute and clears the escrow dispute link + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 10 | + 11 | beforeEach(async () => { + > 12 | const moduleRef = await Test.createTestingModule({ + | ^ + 13 | providers: [DisputeRepository, EscrowRepository, PrismaService], + 14 | }).compile(); + 15 | + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 5) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/dispute.repository.spec.ts:12:23) + +PASS src/notifications/notifications.module.spec.ts (5.356 s) + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌁ auth for agents [www.vestauth.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:31  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +[Nest] 110477 - 30/07/2026, 08:50:31  ERROR [CacheService] Redis connect failed +Connection is closed. +[Nest] 110477 - 30/07/2026, 08:50:31  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +[Nest] 110477 - 30/07/2026, 08:50:31  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +[Nest] 110477 - 30/07/2026, 08:50:32  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +[Nest] 110477 - 30/07/2026, 08:50:32  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +[Nest] 110477 - 30/07/2026, 08:50:32  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +[Nest] 110477 - 30/07/2026, 08:50:32  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +[Nest] 110477 - 30/07/2026, 08:50:33  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +[Nest] 110477 - 30/07/2026, 08:50:33  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +[Nest] 110478 - 30/07/2026, 08:50:33  ERROR [CacheService] Redis connect failed +Connection is closed. +PASS src/app.module.spec.ts (8.474 s) + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ enable debugging { debug: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + + console.warn + API key does not start with "SG.". + + 24 | } + 25 | const client = new MailService(); + > 26 | client.setApiKey(apiKey); + | ^ + 27 | return client; + 28 | } + 29 | + + at Client.setApiKey (node_modules/@sendgrid/client/src/classes/client.js:50:15) + at MailService.setApiKey (node_modules/@sendgrid/mail/src/classes/mail-service.js:38:17) + at InstanceWrapper.createSendGridClient [as metatype] (src/notifications/notifications.module.ts:26:10) + at TestingInjector.instantiateClass (node_modules/@nestjs/core/injector/injector.js:435:55) + at callback (node_modules/@nestjs/core/injector/injector.js:72:45) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:180:24) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 12) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (src/app.module.spec.ts:6:23) + +[Nest] 110477 - 30/07/2026, 08:50:34  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +[Nest] 110477 - 30/07/2026, 08:50:34  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +[Nest] 110477 - 30/07/2026, 08:50:35  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +[Nest] 110477 - 30/07/2026, 08:50:35  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +PASS test/unit/dispute.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ enable debugging { debug: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/throttler.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ custom filepath { path: '/custom/path/.env' } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:36  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +PASS test/unit/rate-limit.integration.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ encrypted .env [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:37  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +PASS test/auth-security.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ secrets for agents [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:37  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +PASS src/tracing/prisma-tracing.wrapper.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ encrypted .env [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110478 - 30/07/2026, 08:50:38  ERROR [StellarWebhookService] {"msg":"stellar.webhook.secret_missing","reason":"STELLAR_WEBHOOK_SECRET is not configured — rejecting request"} +[Nest] 110478 - 30/07/2026, 08:50:38  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-sig-001","txHash":"tx-sig-abc","error":"Webhook secret not configured"} +InternalServerErrorException: Webhook secret not configured + at StellarWebhookService.verifySignature (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:177:13) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:57:12) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.signature.spec.ts:79:28) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +[Nest] 110477 - 30/07/2026, 08:50:38  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +[Nest] 110478 - 30/07/2026, 08:50:38  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-sig-001","txHash":"tx-sig-abc","error":"Invalid webhook signature"} +UnauthorizedException: Invalid webhook signature + at StellarWebhookService.verifySignature (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:199:13) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:57:12) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.signature.spec.ts:155:17) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +[Nest] 110478 - 30/07/2026, 08:50:38  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-sig-001","txHash":"tx-sig-abc","error":"Invalid webhook signature"} +UnauthorizedException: Invalid webhook signature + at StellarWebhookService.verifySignature (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:199:13) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:57:12) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.signature.spec.ts:165:28) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +[Nest] 110478 - 30/07/2026, 08:50:38  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-sig-001","txHash":"tx-sig-abc","error":"Invalid webhook signature"} +UnauthorizedException: Invalid webhook signature + at StellarWebhookService.verifySignature (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:199:13) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:57:12) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.signature.spec.ts:177:28) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +[Nest] 110478 - 30/07/2026, 08:50:38  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-sig-001","txHash":"tx-sig-abc","error":"Invalid webhook signature"} +UnauthorizedException: Invalid webhook signature + at StellarWebhookService.verifySignature (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:199:13) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:57:12) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.signature.spec.ts:190:28) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +[Nest] 110478 - 30/07/2026, 08:50:38  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-sig-001","txHash":"tx-sig-abc","error":"Invalid webhook signature"} +UnauthorizedException: Invalid webhook signature + at StellarWebhookService.verifySignature (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:199:13) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:57:12) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.signature.spec.ts:201:28) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +[Nest] 110478 - 30/07/2026, 08:50:38  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-sig-001","txHash":"tx-sig-abc","error":"Invalid webhook signature"} +UnauthorizedException: Invalid webhook signature + at StellarWebhookService.verifySignature (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:199:13) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:57:12) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.signature.spec.ts:212:17) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +[Nest] 110478 - 30/07/2026, 08:50:38  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-sig-001","txHash":"tx-sig-abc","error":"Missing X-Stellar-Signature header"} +UnauthorizedException: Missing X-Stellar-Signature header + at StellarWebhookService.verifySignature (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:183:13) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:57:12) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.signature.spec.ts:221:28) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +[Nest] 110478 - 30/07/2026, 08:50:38  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-sig-001","txHash":"tx-sig-abc","error":"Missing X-Stellar-Signature header"} +UnauthorizedException: Missing X-Stellar-Signature header + at StellarWebhookService.verifySignature (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:183:13) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:57:12) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.signature.spec.ts:231:28) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +[Nest] 110478 - 30/07/2026, 08:50:38  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-sig-001","txHash":"tx-sig-abc","error":"Invalid webhook signature"} +UnauthorizedException: Invalid webhook signature + at StellarWebhookService.verifySignature (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:199:13) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:57:12) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.signature.spec.ts:257:28) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +PASS test/unit/stellar-webhook.signature.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ secrets for agents [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/cache.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ suppress logs { quiet: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110484 - 30/07/2026, 08:50:38  WARN [CacheService] REDIS_URL not set — using in-memory fallback cache +[Nest] 110484 - 30/07/2026, 08:50:38  WARN [CacheService] REDIS_URL not set — using in-memory fallback cache +[Nest] 110484 - 30/07/2026, 08:50:38  WARN [CacheService] REDIS_URL not set — using in-memory fallback cache +[Nest] 110484 - 30/07/2026, 08:50:38  WARN [CacheService] REDIS_URL not set — using in-memory fallback cache +[Nest] 110484 - 30/07/2026, 08:50:38  WARN [CacheService] REDIS_URL not set — using in-memory fallback cache +[Nest] 110484 - 30/07/2026, 08:50:38  WARN [CacheService] REDIS_URL not set — using in-memory fallback cache +[Nest] 110484 - 30/07/2026, 08:50:38  WARN [CacheService] REDIS_URL not set — using in-memory fallback cache +[Nest] 110484 - 30/07/2026, 08:50:38  WARN [CacheService] REDIS_URL not set — using in-memory fallback cache +[Nest] 110484 - 30/07/2026, 08:50:38  WARN [CacheService] REDIS_URL not set — using in-memory fallback cache +PASS src/vendor/analytics/analytics.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ override existing { override: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:39  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +PASS test/seed.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ enable debugging { debug: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + + console.log + Starting database seed... + + at main (prisma/seed.ts:154:13) + + console.log + Escrows: 15 created, 0 updated + + at main (prisma/seed.ts:158:13) + + console.log + Disputes: 3 created, 0 updated + + at main (prisma/seed.ts:162:13) + + console.log + Notifications: 10 created, 0 updated + + at main (prisma/seed.ts:166:13) + + console.log + + Seed summary: + + at main (prisma/seed.ts:174:13) + + console.log + Escrows: 15 + + at main (prisma/seed.ts:175:13) + + console.log + Disputes: 3 + + at main (prisma/seed.ts:176:13) + + console.log + Notifications: 10 + + at main (prisma/seed.ts:177:13) + + console.log + Seeding completed successfully! + + at main (prisma/seed.ts:178:13) + + console.log + Starting database seed... + + at main (prisma/seed.ts:154:13) + + console.log + Escrows: 15 created, 0 updated + + at main (prisma/seed.ts:158:13) + + console.log + Disputes: 3 created, 0 updated + + at main (prisma/seed.ts:162:13) + + console.log + Notifications: 10 created, 0 updated + + at main (prisma/seed.ts:166:13) + + console.log + + Seed summary: + + at main (prisma/seed.ts:174:13) + + console.log + Escrows: 15 + + at main (prisma/seed.ts:175:13) + + console.log + Disputes: 3 + + at main (prisma/seed.ts:176:13) + + console.log + Notifications: 10 + + at main (prisma/seed.ts:177:13) + + console.log + Seeding completed successfully! + + at main (prisma/seed.ts:178:13) + + console.log + Starting database seed... + + at main (prisma/seed.ts:154:13) + + console.log + Escrows: 15 created, 0 updated + + at main (prisma/seed.ts:158:13) + + console.log + Disputes: 3 created, 0 updated + + at main (prisma/seed.ts:162:13) + + console.log + Notifications: 10 created, 0 updated + + at main (prisma/seed.ts:166:13) + + console.log + + Seed summary: + + at main (prisma/seed.ts:174:13) + + console.log + Escrows: 15 + + at main (prisma/seed.ts:175:13) + + console.log + Disputes: 3 + + at main (prisma/seed.ts:176:13) + + console.log + Notifications: 10 + + at main (prisma/seed.ts:177:13) + + console.log + Seeding completed successfully! + + at main (prisma/seed.ts:178:13) + + console.log + Starting database seed... + + at main (prisma/seed.ts:154:13) + + console.log + Escrows: 0 created, 15 updated + + at main (prisma/seed.ts:158:13) + + console.log + Disputes: 0 created, 3 updated + + at main (prisma/seed.ts:162:13) + + console.log + Notifications: 0 created, 10 updated + + at main (prisma/seed.ts:166:13) + + console.log + + Seed summary: + + at main (prisma/seed.ts:174:13) + + console.log + Escrows: 15 + + at main (prisma/seed.ts:175:13) + + console.log + Disputes: 3 + + at main (prisma/seed.ts:176:13) + + console.log + Notifications: 10 + + at main (prisma/seed.ts:177:13) + + console.log + Seeding completed successfully! + + at main (prisma/seed.ts:178:13) + +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] GET /api/test - 500 - Database error +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] Error: DB problem + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/global-exception.filter.spec.ts:108:41) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +{"method":"GET","url":"/api/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":500,"timestamp":"2026-07-30T07:50:39.988Z"} +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] GET /api/test - 500 - Something went wrong +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] Error: Something went wrong + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/global-exception.filter.spec.ts:166:20) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +{"method":"GET","url":"/api/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":500,"timestamp":"2026-07-30T07:50:40.063Z"} +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] GET /api/test - 500 - Unknown error +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] string error +{"method":"GET","url":"/api/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":500,"timestamp":"2026-07-30T07:50:40.067Z"} +[Nest] 110484 - 30/07/2026, 08:50:39  WARN [GlobalExceptionFilter] GET /api/test - 409 - A record with this data already exists +[Nest] 110484 - 30/07/2026, 08:50:39  WARN [GlobalExceptionFilter] {"method":"GET","url":"/api/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":409,"timestamp":"2026-07-30T07:50:39.975Z"} +[Nest] 110484 - 30/07/2026, 08:50:39  WARN [GlobalExceptionFilter] GET /api/test - 404 - Record not found +[Nest] 110484 - 30/07/2026, 08:50:39  WARN [GlobalExceptionFilter] {"method":"GET","url":"/api/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":404,"timestamp":"2026-07-30T07:50:39.983Z"} +[Nest] 110484 - 30/07/2026, 08:50:40  WARN [GlobalExceptionFilter] GET /api/test - 404 - Not here +[Nest] 110484 - 30/07/2026, 08:50:40  WARN [GlobalExceptionFilter] {"method":"GET","url":"/api/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":404,"timestamp":"2026-07-30T07:50:40.034Z"} +[Nest] 110484 - 30/07/2026, 08:50:40  WARN [GlobalExceptionFilter] GET /api/test - 403 - Forbidden +[Nest] 110484 - 30/07/2026, 08:50:40  WARN [GlobalExceptionFilter] {"method":"GET","url":"/api/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":403,"timestamp":"2026-07-30T07:50:40.041Z"} +[Nest] 110484 - 30/07/2026, 08:50:40  WARN [GlobalExceptionFilter] GET /api/test - 410 - gone +[Nest] 110484 - 30/07/2026, 08:50:40  WARN [GlobalExceptionFilter] {"method":"GET","url":"/api/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":410,"timestamp":"2026-07-30T07:50:40.043Z"} +[Nest] 110484 - 30/07/2026, 08:50:40  WARN [GlobalExceptionFilter] GET /api/test - 400 - Invalid input +[Nest] 110484 - 30/07/2026, 08:50:40  WARN [GlobalExceptionFilter] {"method":"GET","url":"/api/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":400,"timestamp":"2026-07-30T07:50:40.047Z"} +[Nest] 110484 - 30/07/2026, 08:50:40  WARN [GlobalExceptionFilter] GET /api/test - 400 - Field X is required +[Nest] 110484 - 30/07/2026, 08:50:40  WARN [GlobalExceptionFilter] {"method":"GET","url":"/api/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":400,"timestamp":"2026-07-30T07:50:40.051Z"} +[Nest] 110484 - 30/07/2026, 08:50:40  WARN [GlobalExceptionFilter] GET /api/test - 400 - bad +[Nest] 110484 - 30/07/2026, 08:50:40  WARN [GlobalExceptionFilter] {"method":"GET","url":"/api/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":400,"timestamp":"2026-07-30T07:50:40.055Z"} +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] GET /api/test - 500 - Unknown error +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] null +{"method":"GET","url":"/api/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":500,"timestamp":"2026-07-30T07:50:40.077Z"} +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] GET /test - 500 - Internal server error +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] Error: secret detail + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/global-exception.filter.spec.ts:189:24) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +{"method":"GET","url":"/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":500,"timestamp":"2026-07-30T07:50:40.084Z"} +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] GET /api/test - 500 - any +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] Error: any + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/global-exception.filter.spec.ts:197:20) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +{"method":"GET","url":"/api/test","ip":"127.0.0.1","userAgent":"jest-test","requestId":"unknown","statusCode":500,"timestamp":"2026-07-30T07:50:40.091Z"} +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] GET /api/x - 500 - oops +[Nest] 110484 - 30/07/2026, 08:50:40  ERROR [GlobalExceptionFilter] Error: oops + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/global-exception.filter.spec.ts:206:20) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +{"method":"GET","url":"/api/x","ip":"127.0.0.1","userAgent":"jest-test","requestId":"req-abc-123","statusCode":500,"timestamp":"2026-07-30T07:50:40.099Z"} +PASS test/unit/global-exception.filter.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ enable debugging { debug: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:40  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +PASS test/unit/tracing.middleware.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ secrets for agents [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/vendor/analytics/analytics.controller.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ enable debugging { debug: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/admin/queues/queue-dashboard.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ enable debugging { debug: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:41  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +PASS test/unit/tracing.interceptor.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ custom filepath { path: '/custom/path/.env' } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/auth/sep10/sep10.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ override existing { override: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:42  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +PASS src/dlq/dlq.controller.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ custom filepath { path: '/custom/path/.env' } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:43  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +PASS test/unit/horizon.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ secrets for agents [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/tracing.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ multiple files { path: ['.env.local', '.env'] } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/vendor-profile.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ encrypted .env [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:44  ERROR [CacheService] Redis connection error +connect ECONNREFUSED 127.0.0.1:6379 +PASS test/unit/buyer-dispute.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ encrypted .env [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110478 - 30/07/2026, 08:50:44  ERROR [EventReplayService] Failed to process replayed op +[Nest] 110478 - 30/07/2026, 08:50:44  ERROR [EventReplayService] Error: processing error + at Object. (/home/semicolon/Drip/trust-link-backend/src/stellar/event-replay.service.spec.ts:167:32) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +PASS src/stellar/event-replay.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ encrypted .env [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/auth/guards/jwt.guard.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ override existing { override: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +FAIL src/escrow/escrow.evidence-upload.spec.ts (28.029 s) + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ enable debugging { debug: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + + console.warn + API key does not start with "SG.". + + 24 | } + 25 | const client = new MailService(); + > 26 | client.setApiKey(apiKey); + | ^ + 27 | return client; + 28 | } + 29 | + + at Client.setApiKey (node_modules/@sendgrid/client/src/classes/client.js:50:15) + at MailService.setApiKey (node_modules/@sendgrid/mail/src/classes/mail-service.js:38:17) + at InstanceWrapper.createSendGridClient [as metatype] (src/notifications/notifications.module.ts:26:10) + at TestingInjector.instantiateClass (node_modules/@nestjs/core/injector/injector.js:435:55) + at callback (node_modules/@nestjs/core/injector/injector.js:72:45) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:180:24) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 12) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (src/escrow/escrow.evidence-upload.spec.ts:22:42) + + ● Evidence Upload Rate Limiting (e2e) › POST /escrow/evidence-upload › should allow requests within rate limit + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › POST /escrow/evidence-upload › should return 429 when rate limit is exceeded + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › POST /escrow/evidence-upload › should include Retry-After header in 429 response + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › POST /escrow/evidence-upload › should reset rate limit after TTL expires + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › POST /escrow/evidence-upload › should rate limit per IP (different tokens share the same IP limit) + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › POST /escrow/evidence-upload › should allow legitimate uploads within normal usage patterns + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › Environment Variable Configuration › should use default values when env vars are not set + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › Environment Variable Configuration › should use custom values from env vars + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + +PASS test/unit/sep10-nonce-cleanup.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ enable debugging { debug: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/queue-dashboard.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ custom filepath { path: '/custom/path/.env' } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/auto-release.worker.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ enable debugging { debug: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/blockchain-listener.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ secrets for agents [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110484 - 30/07/2026, 08:50:47  ERROR [StellarWebhookService] {"msg":"stellar.replay.processing_failed","eventType":"payment","operationId":"op-001","txHash":"txhash001","error":"Payment event missing destination address"} +BadRequestException: Payment event missing destination address + at StellarWebhookService.handlePayment (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:253:13) + at StellarWebhookService.processEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:218:20) + at StellarWebhookService.processOperationDto (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:134:18) + at runPayment (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.spec.ts:134:20) + at Object. (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.spec.ts:319:18) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +PASS src/webhooks/stellar-webhook.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ secrets for agents [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/auto-release.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ override existing { override: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110478 - 30/07/2026, 08:50:47  ERROR [TrackingPollWorker] {"msg":"tracking_poll.escrow_failed","escrowId":"escrow-fail","trackingId":"TRK-FAIL","eventType":"tracking_poll","error":"carrier timeout"} +Error: carrier timeout + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/tracking-poll.worker.intervals.spec.ts:216:33) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-mock/build/index.js:305:39 + at Object. (/home/semicolon/Drip/trust-link-backend/node_modules/jest-mock/build/index.js:312:13) + at Object.mockConstructor [as getStatus] (/home/semicolon/Drip/trust-link-backend/node_modules/jest-mock/build/index.js:102:19) + at TrackingPollWorker.run (/home/semicolon/Drip/trust-link-backend/src/workers/tracking-poll.worker.ts:51:54) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/tracking-poll.worker.intervals.spec.ts:222:7) +PASS test/unit/tracking-poll.worker.intervals.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌁ auth for agents [www.vestauth.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/config/config.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ enable debugging { debug: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:48  ERROR [AppController] Database health check failed: connection refused +PASS test/unit/vendor-escrows-query.dto.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ custom filepath { path: '/custom/path/.env' } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:49  ERROR [AppController] Database health check failed: connection refused +[Nest] 110477 - 30/07/2026, 08:50:49  ERROR [AppController] Database health check failed: connection refused +[Nest] 110477 - 30/07/2026, 08:50:49  ERROR [AppController] Database health check failed: connection refused +[Nest] 110477 - 30/07/2026, 08:50:49  ERROR [AppController] Horizon health check failed: network timeout +[Nest] 110477 - 30/07/2026, 08:50:49  ERROR [AppController] Horizon health check failed: Horizon returned status 502 +PASS src/app.controller.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ enable debugging { debug: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/vendor/vendor-account-details.controller.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ suppress logs { quiet: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/stellar/cursor.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ encrypted .env [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/escrow-tracking.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌁ auth for agents [www.vestauth.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/common/validators/stellar-address.validator.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ encrypted .env [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/contract.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ override existing { override: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110484 - 30/07/2026, 08:50:50  ERROR [AutoReleaseWorker] {"msg":"auto_release.escrow_failed","escrowId":"escrow-fail","eventType":"auto_release","error":"Stellar RPC timeout"} +Error: Stellar RPC timeout + at Object. (/home/semicolon/Drip/trust-link-backend/src/workers/auto-release.worker.spec.ts:171:32) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +PASS src/workers/auto-release.worker.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ secrets for agents [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110484 - 30/07/2026, 08:50:50  LOG [AutoReleaseWorker] Batch complete: 0 succeeded, 0 failed out of 0 total +[Nest] 110484 - 30/07/2026, 08:50:50  LOG [AutoReleaseWorker] Batch complete: 0 succeeded, 0 failed out of 1 total +[Nest] 110484 - 30/07/2026, 08:50:50  LOG [AutoReleaseWorker] Batch complete: 0 succeeded, 0 failed out of 1 total +[Nest] 110484 - 30/07/2026, 08:50:50  LOG [AutoReleaseWorker] Batch complete: 0 succeeded, 0 failed out of 1 total +[Nest] 110484 - 30/07/2026, 08:50:50  LOG [AutoReleaseWorker] Batch complete: 1 succeeded, 0 failed out of 1 total +[Nest] 110484 - 30/07/2026, 08:50:50  LOG [AutoReleaseWorker] Batch complete: 0 succeeded, 0 failed out of 1 total +[Nest] 110484 - 30/07/2026, 08:50:50  LOG [AutoReleaseWorker] Batch complete: 1 succeeded, 1 failed out of 2 total +[Nest] 110484 - 30/07/2026, 08:50:50  WARN [AutoReleaseWorker] Failed escrows: escrow-fail (Stellar RPC timeout) +[Nest] 110478 - 30/07/2026, 08:50:51  ERROR [StellarWebhookService] {"msg":"stellar.webhook.secret_missing","reason":"STELLAR_WEBHOOK_SECRET is not configured — rejecting request"} +[Nest] 110478 - 30/07/2026, 08:50:51  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-001","txHash":"tx-abc123","error":"Webhook secret not configured"} +InternalServerErrorException: Webhook secret not configured + at StellarWebhookService.verifySignature (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:177:13) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:57:12) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.service.spec.ts:91:26) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +[Nest] 110478 - 30/07/2026, 08:50:51  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-001","txHash":"tx-abc123","error":"Invalid webhook signature"} +UnauthorizedException: Invalid webhook signature + at StellarWebhookService.verifySignature (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:199:13) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:57:12) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.service.spec.ts:114:26) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +[Nest] 110478 - 30/07/2026, 08:50:51  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-001","txHash":"tx-abc123","error":"Missing X-Stellar-Signature header"} +UnauthorizedException: Missing X-Stellar-Signature header + at StellarWebhookService.verifySignature (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:183:13) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:57:12) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.service.spec.ts:124:26) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +[Nest] 110478 - 30/07/2026, 08:50:51  ERROR [StellarWebhookService] {"msg":"stellar.webhook.processing_failed","eventType":"payment","operationId":"op-001","txHash":"tx-abc123","error":"Payment event missing destination address"} +BadRequestException: Payment event missing destination address + at StellarWebhookService.handlePayment (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:253:13) + at StellarWebhookService.processEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:218:20) + at StellarWebhookService.handleEvent (/home/semicolon/Drip/trust-link-backend/src/webhooks/stellar-webhook.service.ts:85:20) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/stellar-webhook.service.spec.ts:204:26) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +PASS test/unit/stellar-webhook.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌁ auth for agents [www.vestauth.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/dlq/dlq.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ secrets for agents [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/escrow/escrow.repository.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ encrypted .env [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/nonce-cleanup.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌁ auth for agents [www.vestauth.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/escrow-tracking-cache.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ enable debugging { debug: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/escrow/dto/vendor-escrows-query.dto.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ secrets for agents [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/tracing.bootstrap.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ custom filepath { path: '/custom/path/.env' } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110484 - 30/07/2026, 08:50:53  ERROR [TrackingPollWorker] {"msg":"tracking_poll.escrow_failed","escrowId":"escrow-1","trackingId":"TRK-1","eventType":"tracking_poll","error":"carrier down"} +Error: carrier down + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/tracking-poll.worker.spec.ts:94:50) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) +PASS test/unit/tracking-poll.worker.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ custom filepath { path: '/custom/path/.env' } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:53  ERROR [EscrowService] Failed to ship escrow escrow-1: Only the escrow vendor or admin can ship this order +[Nest] 110477 - 30/07/2026, 08:50:53  ERROR [EscrowService] ForbiddenException: Only the escrow vendor or admin can ship this order + at EscrowService.handleShipment (/home/semicolon/Drip/trust-link-backend/src/escrow/escrow.service.ts:429:15) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/escrow.service.spec.ts:86:5) { + response: { + message: 'Only the escrow vendor or admin can ship this order', + error: 'Forbidden', + statusCode: 403 + }, + status: 403, + options: {} +} +[Nest] 110477 - 30/07/2026, 08:50:53  ERROR [EscrowService] Failed to ship escrow escrow-1: Cannot ship escrow in SHIPPED state. Escrow must be in FUNDED state. +[Nest] 110477 - 30/07/2026, 08:50:53  ERROR [EscrowService] ConflictException: Cannot ship escrow in SHIPPED state. Escrow must be in FUNDED state. + at EscrowService.handleShipment (/home/semicolon/Drip/trust-link-backend/src/escrow/escrow.service.ts:435:15) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/escrow.service.spec.ts:97:5) { + response: { + message: 'Cannot ship escrow in SHIPPED state. Escrow must be in FUNDED state.', + error: 'Conflict', + statusCode: 409 + }, + status: 409, + options: {} +} +[Nest] 110477 - 30/07/2026, 08:50:53  ERROR [EscrowService] Failed to ship escrow escrow-1: Tracking ID is required and cannot be empty +[Nest] 110477 - 30/07/2026, 08:50:53  ERROR [EscrowService] BadRequestException: Tracking ID is required and cannot be empty + at EscrowService.handleShipment (/home/semicolon/Drip/trust-link-backend/src/escrow/escrow.service.ts:412:15) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/escrow.service.spec.ts:104:15) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) { + response: { + message: 'Tracking ID is required and cannot be empty', + error: 'Bad Request', + statusCode: 400 + }, + status: 400, + options: {} +} +[Nest] 110477 - 30/07/2026, 08:50:53  ERROR [EscrowService] Failed to ship escrow missing: Escrow with ID missing not found +[Nest] 110477 - 30/07/2026, 08:50:54  ERROR [EscrowService] NotFoundException: Escrow with ID missing not found + at EscrowService.findById (/home/semicolon/Drip/trust-link-backend/src/escrow/escrow.service.ts:189:15) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at EscrowService.handleShipment (/home/semicolon/Drip/trust-link-backend/src/escrow/escrow.service.ts:423:22) + at Object. (/home/semicolon/Drip/trust-link-backend/test/unit/escrow.service.spec.ts:112:5) { + response: { + message: 'Escrow with ID missing not found', + error: 'Not Found', + statusCode: 404 + }, + status: 404, + options: {} +} +PASS test/unit/escrow.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ secrets for agents [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/logistics/gigl/gigl-logistics.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌁ auth for agents [www.vestauth.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/dlq.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ override existing { override: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110484 - 30/07/2026, 08:50:54  WARN [DlqService] {"msg":"dlq.replay.failed","failedTransactionId":"test-id-1","operation":"submitAutoRelease","attempts":2,"error":"still failing"} +[Nest] 110484 - 30/07/2026, 08:50:54  ERROR [NotificationRetryQueueService] Notification FUNDED/EMAIL for escrow escrow-1 exhausted 3 attempts — moved to DLQ (requestId: req-1) +PASS test/unit/notification-retry-queue.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ encrypted .env [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/admin.guard.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ suppress logs { quiet: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110484 - 30/07/2026, 08:50:54  WARN [NotificationRetryQueueService] Retry attempt 1/3 for FUNDED/EMAIL (requestId: 2664284d-d076-4bfd-a8f7-894fcdc3bb8b) — next retry in 1ms +[Nest] 110484 - 30/07/2026, 08:50:54  WARN [NotificationRetryQueueService] Retry attempt 2/3 for FUNDED/EMAIL (requestId: 2664284d-d076-4bfd-a8f7-894fcdc3bb8b) — next retry in 2ms +[Nest] 110484 - 30/07/2026, 08:50:54  WARN [NotificationRetryQueueService] Retry attempt 1/3 for FUNDED/EMAIL (requestId: req-1) — next retry in 1ms +[Nest] 110484 - 30/07/2026, 08:50:54  WARN [NotificationRetryQueueService] Retry attempt 2/3 for FUNDED/EMAIL (requestId: req-1) — next retry in 2ms +[Nest] 110484 - 30/07/2026, 08:50:54  WARN [NotificationRetryQueueService] No dispatcher registered for channel EMAIL; dropping job 609fa2eb-5029-4016-bad8-7e602d7659b4 +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Starting stress test: test-run (ID: test_1785397854724_zagppq4iv) +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Executing profile 1/1 +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Profile 0: 2 concurrent users, 2 req/s, duration: 1s +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Stress test completed: test-run +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] [OK] No performance alerts generated +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Starting stress test: test-run (ID: test_1785397854732_c8pr50gh6) +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Executing profile 1/1 +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Profile 0: 3 concurrent users, 3 req/s, duration: 1s +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Stress test completed: test-run +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] [OK] No performance alerts generated +[Nest] 110477 - 01/01/1970, 01:00:00  LOG [StressTestService] Starting stress test: test-run (ID: test_10_w1ow8t52n) +[Nest] 110477 - 01/01/1970, 01:00:00  LOG [StressTestService] Executing profile 1/1 +[Nest] 110477 - 01/01/1970, 01:00:00  LOG [StressTestService] Profile 0: 1 concurrent users, 10 req/s, duration: 1s +[Nest] 110477 - 01/01/1970, 01:00:00  LOG [StressTestService] Stress test completed: test-run +[Nest] 110477 - 01/01/1970, 01:00:00  LOG [StressTestService] [OK] No performance alerts generated +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Starting stress test: test-run (ID: test_1785397854753_7hzrcwbaw) +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Executing profile 1/1 +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Profile 0: 1 concurrent users, 2 req/s, duration: 1s +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Stress test completed: test-run +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] [OK] No performance alerts generated +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Starting stress test: test-run (ID: test_1785397854758_kp22ixthf) +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Executing profile 1/1 +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Profile 0: 2 concurrent users, 2 req/s, duration: 1s +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Stress test completed: test-run +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] [OK] No performance alerts generated +PASS src/stress-test/stress-test.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ encrypted .env [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Starting stress test: test-run (ID: test_1785397854762_09oihcfkz) +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Executing profile 1/1 +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Profile 0: 1 concurrent users, 1 req/s, duration: 1s +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Stress test completed: test-run +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] [OK] No performance alerts generated +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Starting stress test: test-run (ID: test_1785397854764_32i211bnr) +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Executing profile 1/1 +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Profile 0: 1 concurrent users, 1 req/s, duration: 1s +[Nest] 110477 - 30/07/2026, 08:50:54  LOG [StressTestService] Stress test completed: test-run +[Nest] 110477 - 30/07/2026, 08:50:54  WARN [StressTestService] [WARN] Generated 1 performance alerts: +[Nest] 110477 - 30/07/2026, 08:50:54  WARN [StressTestService] [WARN] [THROUGHPUT_DROP] Throughput 1.00 req/s below threshold 999999 req/s (Value: 1.00, Threshold: 999999) +[Nest] 110484 - 30/07/2026, 08:50:55  ERROR [NotificationsService] SendGrid FUNDED notification failed after 3 attempts [Request-ID: 18c93d81-32e1-4791-beeb-27a658fe1cb8] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid FUNDED [attempt 1/3, Request-ID: 6416b735-3f2c-42ff-bf47-1a574075d692] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching Twilio FUNDED [attempt 1/3, Request-ID: ce312153-43d3-4e96-9718-17d2ba86654f] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid FUNDED [attempt 1/3, Request-ID: 73ab19c3-b6bc-4953-b3b6-87509b7abbe6] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching Twilio FUNDED [attempt 1/3, Request-ID: 137943f8-b31a-4929-97eb-f9c3fabd2fd0] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid DISPUTED [attempt 1/3, Request-ID: 32c62c8a-a5eb-4e05-a26c-bf84680f4dd3] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching Twilio DISPUTED [attempt 1/3, Request-ID: 5fd0a142-453d-468c-a5b8-9f0ada9c5bc1] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid FUNDED [attempt 1/3, Request-ID: a7bad11b-929a-4490-a123-c46a8ab7789d] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching Twilio FUNDED [attempt 1/3, Request-ID: ab3e6b7f-e1c1-47c5-9061-2cbf57f9b63b] +[Nest] 110484 - 30/07/2026, 08:50:55  WARN [NotificationsService] No buyer contact info for escrow esc-1 — falling back to Stellar address +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid SHIPPED [attempt 1/3, Request-ID: 14c41945-c61b-4e2b-8d98-64aa9a5553ac] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching Twilio SHIPPED [attempt 1/3, Request-ID: c1fca961-58bc-42ee-9e02-457b0bc8f1d9] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid FUNDED [attempt 1/3, Request-ID: 34d4cc0a-60a9-4b31-89d3-bd3cf6a7c2ef] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching Twilio FUNDED [attempt 1/3, Request-ID: f5877fe3-1ce8-4a19-8597-9d0bdfd0fdad] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid DISPUTED [attempt 1/3, Request-ID: e1edc292-15a3-4618-943a-3a7ff357fe8f] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching Twilio DISPUTED [attempt 1/3, Request-ID: 6659dac2-6c6f-4444-b167-97f1e22fde39] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid FUNDED [attempt 1/3, Request-ID: da8b11b2-141b-43a9-a81c-b4ebb0e2c2a6] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching Twilio FUNDED [attempt 1/3, Request-ID: 8c841a3b-0acb-4e7d-bfe5-d13317974bae] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid DISPUTED [attempt 1/3, Request-ID: 95322efa-c8a6-4d94-8c3c-88cc1c43e8e4] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching Twilio DISPUTED [attempt 1/3, Request-ID: 1de36ce7-707f-4d4e-af7f-c5f365a66be1] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid FUNDED [attempt 1/3, Request-ID: 2652ceef-94d0-4495-bcb9-463c98fdac48] +[Nest] 110484 - 30/07/2026, 08:50:55  WARN [NotificationsService] SendGrid FUNDED attempt 1/3 failed (status: 429) — retrying in 1000ms [Request-ID: 2652ceef-94d0-4495-bcb9-463c98fdac48] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid FUNDED [attempt 2/3, Request-ID: 2652ceef-94d0-4495-bcb9-463c98fdac48] +[Nest] 110484 - 30/07/2026, 08:50:55  WARN [NotificationsService] SendGrid FUNDED attempt 2/3 failed (status: 429) — retrying in 2000ms [Request-ID: 2652ceef-94d0-4495-bcb9-463c98fdac48] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid FUNDED [attempt 3/3, Request-ID: 2652ceef-94d0-4495-bcb9-463c98fdac48] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching Twilio FUNDED [attempt 1/3, Request-ID: 7266fee1-05a9-4120-966a-50c9179b9ea0] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid FUNDED [attempt 1/3, Request-ID: 18c93d81-32e1-4791-beeb-27a658fe1cb8] +[Nest] 110484 - 30/07/2026, 08:50:55  WARN [NotificationsService] SendGrid FUNDED attempt 1/3 failed (status: 500) — retrying in 1000ms [Request-ID: 18c93d81-32e1-4791-beeb-27a658fe1cb8] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid FUNDED [attempt 2/3, Request-ID: 18c93d81-32e1-4791-beeb-27a658fe1cb8] +[Nest] 110484 - 30/07/2026, 08:50:55  WARN [NotificationsService] SendGrid FUNDED attempt 2/3 failed (status: 500) — retrying in 2000ms [Request-ID: 18c93d81-32e1-4791-beeb-27a658fe1cb8] +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching SendGrid FUNDED [attempt 3/3, Request-ID: 18c93d81-32e1-4791-beeb-27a658fe1cb8] +[Nest] 110484 - 30/07/2026, 08:50:55  ERROR [NotificationsService] Error: server error + at Object. (/home/semicolon/Drip/trust-link-backend/src/notifications/notifications.service.spec.ts:185:23) + at Promise.finally.completed (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1561:28) + at new Promise () + at callAsyncCircusFn (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1501:10) + at _callCircusTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1011:40) + at processTicksAndRejections (node:internal/process/task_queues:104:5) + at _runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:951:3) + at /home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:853:7 + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:866:11) + at _runTestsForDescribeBlock (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:861:11) + at run (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:765:3) + at runAndTransformResultsToJestFormat (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/jestAdapterInit.js:1993:21) + at jestAdapter (/home/semicolon/Drip/trust-link-backend/node_modules/jest-circus/build/runner.js:111:19) + at runTestInternal (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:276:16) + at runTest (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:344:7) + at Object.worker (/home/semicolon/Drip/trust-link-backend/node_modules/jest-runner/build/testWorker.js:498:12) { + code: 500 +} +PASS src/notifications/notifications.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ multiple files { path: ['.env.local', '.env'] } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110484 - 30/07/2026, 08:50:55  LOG [NotificationsService] Dispatching Twilio FUNDED [attempt 1/3, Request-ID: dc171dac-aa66-4e21-b30d-fae6830aa027] +PASS src/prisma/escrow-event-logging.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ suppress logs { quiet: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"EscrowFunded","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"EscrowFunded","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"EscrowFunded","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"EscrowShipped","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"EscrowShipped","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"EscrowCompleted","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"EscrowCompleted","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"DisputeRaised","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"DisputeRaised","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"DisputeResolved","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"DisputeResolved","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"AutoReleased","escrowId":"escrow-1"} +PASS src/escrow/escrow.service.sync-state.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ custom filepath { path: '/custom/path/.env' } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"AutoReleased","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"EscrowFunded","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  WARN [EscrowService] {"msg":"escrow.sync.not_found","eventType":"EscrowFunded","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  LOG [EscrowService] {"msg":"escrow.sync.received","eventType":"UnknownEvent","escrowId":"escrow-1"} +[Nest] 110477 - 30/07/2026, 08:50:55  WARN [EscrowService] {"msg":"escrow.sync.unknown_event","eventType":"UnknownEvent","escrowId":"escrow-1"} +PASS src/common/validators/file-type.validator.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌁ auth for agents [www.vestauth.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/admin/stats/admin-stats.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ enable debugging { debug: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/common/sanitization/credential-encryption.util.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ secrets for agents [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/escrow-auto-release-index.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ custom filepath { path: '/custom/path/.env' } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/vendor/vendor-upsert.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ encrypted .env [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/prisma-schema-parity.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌁ auth for agents [www.vestauth.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/prisma/prisma.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ override existing { override: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/json-logger.service.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ custom filepath { path: '/custom/path/.env' } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/dispute/dispute.repository.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ encrypted .env [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/vendor/vendor-account-details.repository.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ◈ secrets for agents [www.dotenvx.com] + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/escrow/escrow-viewer.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ multiple files { path: ['.env.local', '.env'] } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS test/unit/vendor-dashboard-index.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ multiple files { path: ['.env.local', '.env'] } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +PASS src/common/security/csp.config.spec.ts + ● Console + + console.log + ◇ injected env (14) from .env.test // tip: ⌘ suppress logs { quiet: true } + + at _log (node_modules/dotenv/lib/main.js:131:11) + +A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --detectOpenHandles to find leaks. Active timers can also cause this, ensure that .unref() was called on them. + +Summary of all failing tests +FAIL test/unit/logistics.service.spec.ts (6.212 s) + ● LogisticsService & LogisticsModule (issue #479) › Provider lookups via LogisticsModule (configured vs unconfigured) › handles provider timeout (network error) + + expect(received).rejects.toThrow(expected) + + Expected constructor: GiglNetworkError + Received constructor: Error + + Received message: "request timed out" + + 123 | + 124 | it('handles provider timeout (network error)', async () => { + > 125 | const timeoutError = new Error('request timed out') as any; + | ^ + 126 | timeoutError.isAxiosError = true; + 127 | timeoutError.code = 'ECONNABORTED'; + 128 | + + at Object. (test/unit/logistics.service.spec.ts:125:28) + at Object.toThrow (node_modules/expect/build/index.js:2155:20) + at Object. (test/unit/logistics.service.spec.ts:137:66) + + ● LogisticsService & LogisticsModule (issue #479) › Provider lookups via LogisticsModule (configured vs unconfigured) › handles 404 response (provider error) + + expect(received).rejects.toThrow(expected) + + Expected constructor: GiglProviderError + Received constructor: Error + + Received message: "Not found" + + 141 | + 142 | it('handles 404 response (provider error)', async () => { + > 143 | const notFoundError = new Error('Not found') as any; + | ^ + 144 | notFoundError.isAxiosError = true; + 145 | notFoundError.response = { status: 404 }; + 146 | + + at Object. (test/unit/logistics.service.spec.ts:143:29) + at Object.toThrow (node_modules/expect/build/index.js:2155:20) + at Object. (test/unit/logistics.service.spec.ts:155:62) + + ● LogisticsService & LogisticsModule (issue #479) › Provider lookups via LogisticsModule (configured vs unconfigured) › fails clearly and logs warning at startup when unconfigured + + expect(jest.fn()).toHaveBeenCalledWith(...expected) + + Expected: StringContaining "Logistics provider is not configured" + + Number of calls: 0 + + 181 | logisticsService.onModuleInit(); + 182 | + > 183 | expect(loggerSpy).toHaveBeenCalledWith( + | ^ + 184 | expect.stringContaining('Logistics provider is not configured'), + 185 | ); + 186 | + + at Object. (test/unit/logistics.service.spec.ts:183:25) + +FAIL src/config/config.module.spec.ts (6.955 s) + ● ConfigModule — Stellar Key Validation › valid Stellar keys pass validation › accepts a genuine valid SEP10_SIGNING_SECRET + + expect(received).toBe(expected) // Object.is equality + + Expected: "SDWG7OPXKSKX2JMFVO2C4W37DA56UKOZIUYP34COSENTJ53OIYMYYS4V" + Received: "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25" + + 115 | const service = await buildConfigService(VALID_ENV); + 116 | expect(service).toBeDefined(); + > 117 | expect(service.get('SEP10_SIGNING_SECRET')).toBe(ANOTHER_VALID_SECRET); + | ^ + 118 | }); + 119 | + 120 | it('accepts a genuine valid ADMIN_ADDRESS', async () => { + + at Object. (src/config/config.module.spec.ts:117:51) + + ● ConfigModule — Stellar Key Validation › checksum-invalid secret keys are rejected at startup › rejects SYSTEM_SIGNER_SECRET with invalid checksum + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 145 | }; + 146 | + > 147 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 148 | }); + 149 | + 150 | it('rejects SEP10_SIGNING_SECRET with invalid checksum', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:147:13) + + ● ConfigModule — Stellar Key Validation › checksum-invalid secret keys are rejected at startup › rejects SEP10_SIGNING_SECRET with invalid checksum + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 154 | }; + 155 | + > 156 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 157 | }); + 158 | + 159 | it('error message for SYSTEM_SIGNER_SECRET names the variable', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:156:13) + + ● ConfigModule — Stellar Key Validation › checksum-invalid secret keys are rejected at startup › error message for SYSTEM_SIGNER_SECRET names the variable + + expect(received).toContain(expected) // indexOf + + Expected substring: "SYSTEM_SIGNER_SECRET" + Received string: "fail is not defined" + + 166 | } catch (error) { + 167 | const message = (error as Error).message; + > 168 | expect(message).toContain('SYSTEM_SIGNER_SECRET'); + | ^ + 169 | } + 170 | }); + 171 | + + at Object. (src/config/config.module.spec.ts:168:25) + + ● ConfigModule — Stellar Key Validation › checksum-invalid secret keys are rejected at startup › error message for SEP10_SIGNING_SECRET names the variable + + expect(received).toContain(expected) // indexOf + + Expected substring: "SEP10_SIGNING_SECRET" + Received string: "fail is not defined" + + 179 | } catch (error) { + 180 | const message = (error as Error).message; + > 181 | expect(message).toContain('SEP10_SIGNING_SECRET'); + | ^ + 182 | } + 183 | }); + 184 | + + at Object. (src/config/config.module.spec.ts:181:25) + + ● ConfigModule — Stellar Key Validation › checksum-invalid secret keys are rejected at startup › error message says "invalid" and does not say "pattern" + + expect(received).toContain(expected) // indexOf + + Expected substring: "invalid" + Received string: "fail is not defined" + + 192 | } catch (error) { + 193 | const message = (error as Error).message; + > 194 | expect(message.toLowerCase()).toContain('invalid'); + | ^ + 195 | expect(message).not.toContain('pattern'); + 196 | } + 197 | }); + + at Object. (src/config/config.module.spec.ts:194:39) + + ● ConfigModule — Stellar Key Validation › checksum-invalid secret keys are rejected at startup › error message mentions checksum verification + + expect(received).toContain(expected) // indexOf + + Expected substring: "checksum" + Received string: "fail is not defined" + + 206 | } catch (error) { + 207 | const message = (error as Error).message; + > 208 | expect(message.toLowerCase()).toContain('checksum'); + | ^ + 209 | } + 210 | }); + 211 | }); + + at Object. (src/config/config.module.spec.ts:208:39) + + ● ConfigModule — Stellar Key Validation › public key rejected where secret key expected › rejects public key (G...) as SYSTEM_SIGNER_SECRET + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 218 | }; + 219 | + > 220 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 221 | }); + 222 | + 223 | it('rejects public key (G...) as SEP10_SIGNING_SECRET', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:220:13) + + ● ConfigModule — Stellar Key Validation › public key rejected where secret key expected › rejects public key (G...) as SEP10_SIGNING_SECRET + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 227 | }; + 228 | + > 229 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 230 | }); + 231 | + 232 | it('error message explains key must start with S for secret key', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:229:13) + + ● ConfigModule — Stellar Key Validation › public key rejected where secret key expected › error message explains key must start with S for secret key + + expect(received).toContain(expected) // indexOf + + Expected substring: "SYSTEM_SIGNER_SECRET" + Received string: "fail is not defined" + + 239 | } catch (error) { + 240 | const message = (error as Error).message; + > 241 | expect(message).toContain('SYSTEM_SIGNER_SECRET'); + | ^ + 242 | expect(message.toLowerCase()).toContain('start'); + 243 | expect(message.toLowerCase()).toContain('s'); + 244 | } + + at Object. (src/config/config.module.spec.ts:241:25) + + ● ConfigModule — Stellar Key Validation › ADMIN_ADDRESS validated as Stellar public key › rejects a secret key (S...) as ADMIN_ADDRESS + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 253 | }; + 254 | + > 255 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 256 | }); + 257 | + 258 | it('rejects arbitrary string as ADMIN_ADDRESS', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:255:13) + + ● ConfigModule — Stellar Key Validation › ADMIN_ADDRESS validated as Stellar public key › rejects arbitrary string as ADMIN_ADDRESS + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 262 | }; + 263 | + > 264 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 265 | }); + 266 | + 267 | it('rejects checksum-invalid public key as ADMIN_ADDRESS', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:264:13) + + ● ConfigModule — Stellar Key Validation › ADMIN_ADDRESS validated as Stellar public key › rejects checksum-invalid public key as ADMIN_ADDRESS + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 271 | }; + 272 | + > 273 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 274 | }); + 275 | + 276 | it('error message names ADMIN_ADDRESS', async () => { + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:273:13) + + ● ConfigModule — Stellar Key Validation › ADMIN_ADDRESS validated as Stellar public key › error message names ADMIN_ADDRESS + + expect(received).toContain(expected) // indexOf + + Expected substring: "ADMIN_ADDRESS" + Received string: "fail is not defined" + + 283 | } catch (error) { + 284 | const message = (error as Error).message; + > 285 | expect(message).toContain('ADMIN_ADDRESS'); + | ^ + 286 | } + 287 | }); + 288 | + + at Object. (src/config/config.module.spec.ts:285:25) + + ● ConfigModule — Stellar Key Validation › ADMIN_ADDRESS validated as Stellar public key › error message for secret key in ADMIN_ADDRESS explains key must start with G + + expect(received).toContain(expected) // indexOf + + Expected substring: "ADMIN_ADDRESS" + Received string: "fail is not defined" + + 296 | } catch (error) { + 297 | const message = (error as Error).message; + > 298 | expect(message).toContain('ADMIN_ADDRESS'); + | ^ + 299 | expect(message.toLowerCase()).toContain('start'); + 300 | expect(message.toLowerCase()).toContain('g'); + 301 | } + + at Object. (src/config/config.module.spec.ts:298:25) + + ● ConfigModule — Stellar Key Validation › ADMIN_ADDRESS validated as Stellar public key › rejects empty string as ADMIN_ADDRESS + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 308 | }; + 309 | + > 310 | await expect(buildConfigService(invalidEnv)).rejects.toThrow(); + | ^ + 311 | }); + 312 | }); + 313 | + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:310:13) + + ● ConfigModule — Stellar Key Validation › Stellar SDK Keypair behavior — unit tests › derived public key matches expected value for known secret + + expect(received).toBe(expected) // Object.is equality + + Expected: "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5" + Received: "GBEFNNUJ3IRKU2JEAMWBA7YI52HF2GYPHMDXF37T75GHK5KU2Y2QSUAJ" + + 347 | it('derived public key matches expected value for known secret', () => { + 348 | const keypair = Keypair.fromSecret(VALID_SECRET_KEY); + > 349 | expect(keypair.publicKey()).toBe(VALID_PUBLIC_KEY); + | ^ + 350 | }); + 351 | }); + 352 | + + at Object. (src/config/config.module.spec.ts:349:35) + + ● ConfigModule — Stellar Key Validation › config validation with mixed valid and invalid keys › fails if only SYSTEM_SIGNER_SECRET is invalid + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 353 | describe('config validation with mixed valid and invalid keys', () => { + 354 | it('fails if only SYSTEM_SIGNER_SECRET is invalid', async () => { + > 355 | await expect( + | ^ + 356 | buildConfigService({ + 357 | ...VALID_ENV, + 358 | SYSTEM_SIGNER_SECRET: CHECKSUM_INVALID_SECRET, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:355:13) + + ● ConfigModule — Stellar Key Validation › config validation with mixed valid and invalid keys › fails if only SEP10_SIGNING_SECRET is invalid + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 362 | + 363 | it('fails if only SEP10_SIGNING_SECRET is invalid', async () => { + > 364 | await expect( + | ^ + 365 | buildConfigService({ + 366 | ...VALID_ENV, + 367 | SEP10_SIGNING_SECRET: CHECKSUM_INVALID_SECRET, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:364:13) + + ● ConfigModule — Stellar Key Validation › config validation with mixed valid and invalid keys › fails if only ADMIN_ADDRESS is invalid + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 371 | + 372 | it('fails if only ADMIN_ADDRESS is invalid', async () => { + > 373 | await expect( + | ^ + 374 | buildConfigService({ + 375 | ...VALID_ENV, + 376 | ADMIN_ADDRESS: RANDOM_STRING, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:373:13) + + ● ConfigModule — Stellar Key Validation › config validation with mixed valid and invalid keys › succeeds when all three Stellar keys are valid + + expect(received).toBe(expected) // Object.is equality + + Expected: "SDWG7OPXKSKX2JMFVO2C4W37DA56UKOZIUYP34COSENTJ53OIYMYYS4V" + Received: "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25" + + 383 | expect(service).toBeDefined(); + 384 | expect(service.get('SYSTEM_SIGNER_SECRET')).toBe(VALID_SECRET_KEY); + > 385 | expect(service.get('SEP10_SIGNING_SECRET')).toBe(ANOTHER_VALID_SECRET); + | ^ + 386 | expect(service.get('ADMIN_ADDRESS')).toBe(VALID_PUBLIC_KEY); + 387 | }); + 388 | }); + + at Object. (src/config/config.module.spec.ts:385:51) + + ● ConfigModule — Stellar Key Validation › abortEarly: false shows all validation errors › reports multiple errors when multiple fields are invalid + + expect(received).toContain(expected) // indexOf + + Expected substring: "SYSTEM_SIGNER_SECRET" + Received string: "fail is not defined" + + 401 | const message = (error as Error).message; + 402 | // With abortEarly: false, should include all field names + > 403 | expect(message).toContain('SYSTEM_SIGNER_SECRET'); + | ^ + 404 | expect(message).toContain('SEP10_SIGNING_SECRET'); + 405 | expect(message).toContain('ADMIN_ADDRESS'); + 406 | } + + at Object. (src/config/config.module.spec.ts:403:25) + + ● ConfigModule — Stellar Key Validation › edge cases and regression tests › rejects Stellar address with wrong prefix (T... or invalid prefix) + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 414 | + 415 | // This will fail at the shape check level + > 416 | await expect( + | ^ + 417 | buildConfigService({ + 418 | ...VALID_ENV, + 419 | SYSTEM_SIGNER_SECRET: invalidPrefix, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:416:13) + + ● ConfigModule — Stellar Key Validation › edge cases and regression tests › rejects secret key that is too short + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 425 | const tooShort = 'SAAAA'; + 426 | + > 427 | await expect( + | ^ + 428 | buildConfigService({ + 429 | ...VALID_ENV, + 430 | SYSTEM_SIGNER_SECRET: tooShort, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:427:13) + + ● ConfigModule — Stellar Key Validation › edge cases and regression tests › rejects secret key with invalid Base32 characters + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 437 | const invalidChar = 'SOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; + 438 | + > 439 | await expect( + | ^ + 440 | buildConfigService({ + 441 | ...VALID_ENV, + 442 | SYSTEM_SIGNER_SECRET: invalidChar, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:439:13) + + ● ConfigModule — Stellar Key Validation › edge cases and regression tests › rejects public key with invalid Base32 characters + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 449 | const invalidChar = 'GOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; + 450 | + > 451 | await expect( + | ^ + 452 | buildConfigService({ + 453 | ...VALID_ENV, + 454 | ADMIN_ADDRESS: invalidChar, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:451:13) + + ● ConfigModule — Stellar Key Validation › edge cases and regression tests › real-world scenario: typo in last char of secret key is caught + + expect(received).rejects.toThrow() + + Received promise resolved instead of rejected + Resolved to value: {"nestConfigService": {"_changes$": {"closed": false, "currentObservers": null, "hasError": false, "isStopped": false, "observers": [], "thrownError": null}, "_isCacheEnabled": false, "_skipProcessEnv": false, "cache": {}, "envFilePaths": ["/home/semicolon/Drip/trust-link-backend/.env"], "internalConfig": {"_PROCESS_ENV_VALIDATED": {"ADMIN_ADDRESS": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "ALLOWED_ORIGINS": "http://localhost:3000,http://localhost:3001", "ANTIGRAVITY_AGENT": "1", "ANTIGRAVITY_EDITOR_APP_ROOT": "/usr/share/antigravity/resources/app", "ANTIGRAVITY_TRAJECTORY_ID": "8b270727-c183-411d-aaac-0b5c42330e48", "AUTH_CHALLENGE_LIMIT": "10", "AUTH_CHALLENGE_WINDOW": "60000", "AUTO_RELEASE_SOURCE_ADDRESS": "GAGRQY3NU3KFQMBABDJBSJKMT6LSTC2RXAYSAMSYB3Y6XUZRHI3ZGR7T", "CHROME_DESKTOP": "antigravity.desktop", "CINNAMON_VERSION": "6.4.8", "CLUTTER_IM_MODULE": "ibus", "COLOR": "0", "CONTACT_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "CONTRACT_ID": "test-contract-id", "CREDENTIAL_ENCRYPTION_KEY": "0000000000000000000000000000000000000000000000000000000000000000", "DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/trustlink_test", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus", "DB_POOL_CONNECTION_LIMIT": 10, "DB_POOL_TIMEOUT_MS": 10000, "DESKTOP_SESSION": "cinnamon", "DISPLAY": ":0", "EDITOR": "vi", "FC_FONTATIONS": "1", "GDK_BACKEND": "x11", "GDMSESSION": "cinnamon", "GDM_LANG": "en_US", "GIGL_API_BASE_URL": "https://api.gigl.com/v1", "GIGL_API_TOKEN": "your-gigl-api-token", "GIO_LAUNCHED_DESKTOP_FILE": "/usr/share/applications/antigravity.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "108499", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_KEYRING_CONTROL": "/run/user/1000/keyring", "GPG_AGENT_INFO": "/run/user/1000/gnupg/S.gpg-agent:0:1", "GTK3_MODULES": "xapp-gtk3-module", "GTK_IM_MODULE": "ibus", "GTK_MODULES": "gail:atk-bridge", "HOME": "/home/semicolon", "INIT_CWD": "/home/semicolon/Drip/trust-link-backend", "INSIDE_NEMO_PYTHON": "", "JEST_WORKER_ID": "2", "LANG": "en_NG", "LANGUAGE": "en_NG:en", "LESSCLOSE": "/usr/bin/lesspipe %s %s", "LESSOPEN": "| /usr/bin/lesspipe %s", "LOGNAME": "semicolon", "LOG_LEVEL": "info", "LS_COLORS": "", "NEXT_PUBLIC_STELLAR_NETWORK": "TESTNET", "NODE": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "NODE_ENV": "test", "NONCE_TTL": "900", "NVM_BIN": "/home/semicolon/.nvm/versions/node/v24.14.0/bin", "NVM_CD_FLAGS": "", "NVM_DIR": "/home/semicolon/.nvm", "NVM_INC": "/home/semicolon/.nvm/versions/node/v24.14.0/include/node", "OTEL_ENABLED": "true", "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", "OTEL_SERVICE_NAME": "trustlink-backend", "OTEL_SERVICE_VERSION": "1.0.0", "PAGER": "cat", "PATH": "/home/semicolon/Drip/trust-link-backend/node_modules/.bin:/home/semicolon/Drip/node_modules/.bin:/home/semicolon/node_modules/.bin:/home/node_modules/.bin:/node_modules/.bin:/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/semicolon/.local/bin:/home/semicolon/.cargo/bin:/home/semicolon/.nvm/versions/node/v24.14.0/bin:/home/semicolon/.cargo/bin:/home/semicolon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/semicolon/.local/share/JetBrains/Toolbox/scripts:/home/semicolon/.local/share/JetBrains/Toolbox/scripts", "PORT": 3001, "PUBLIC_LIMIT": "60", "PUBLIC_WINDOW": "60000", "PWD": "/home/semicolon/Drip/trust-link-backend", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "REDIS_URL": "redis://localhost:6379", "REFRESH_TOKEN_TTL": "604800", "SENDGRID_API_KEY": "your-sendgrid-api-key", "SENTRY_DSN": "http://public@localhost/1", "SEP10_JWT_SECRET": "test-jwt-secret-32-characters-long!!", "SEP10_SIGNING_SECRET": "SCMKMBTJDWJ4WLWKYGCXRZUDXS4SNRRR6GIADYQXKVK7CCHI2FN2QV25", "SESSION_MANAGER": "local/semicolon-Latitude-7480:@/tmp/.ICE-unix/1053,unix/semicolon-Latitude-7480:/tmp/.ICE-unix/1053", "SHELL": "/bin/bash", "SHLVL": "1", "SSH_AUTH_SOCK": "/run/user/1000/keyring/ssh", "STELLAR_HORIZON_URL": "https://horizon-testnet.stellar.org", "STELLAR_NETWORK": "TESTNET", "STELLAR_WEBHOOK_SECRET": "your-stellar-webhook-hmac-secret", "SYSTEM_SIGNER_SECRET": "SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35C", "TERM": "dumb", "TS_JEST": "1", "TWILIO_ACCOUNT_SID": "AC00000000000000000000000000000000", "TWILIO_AUTH_TOKEN": "00000000000000000000000000000000", "USER": "semicolon", "VSCODE_CODE_CACHE_PATH": "/home/semicolon/.config/Antigravity/CachedData/15487b3041e65228cae24980a3f796c905ef582c", "VSCODE_CWD": "/home/semicolon", "VSCODE_IPC_HOOK": "/run/user/1000/vscode-41ffa4d7-1.10-main.sock", "VSCODE_NLS_CONFIG": "{\"userLocale\":\"en-gb\",\"osLocale\":\"en-ng\",\"resolvedLanguage\":\"en\",\"defaultMessagesFile\":\"/usr/share/antigravity/resources/app/out/nls.messages.json\",\"locale\":\"en-gb\",\"availableLanguages\":{}}", "VSCODE_PID": "108499", "XAUTHORITY": "/home/semicolon/.Xauthority", "XDG_CONFIG_DIRS": "/etc/xdg/xdg-cinnamon:/etc/xdg", "XDG_CURRENT_DESKTOP": "X-Cinnamon", "XDG_DATA_DIRS": "/usr/share/gnome:/usr/share/cinnamon:/usr/share/gnome:/home/semicolon/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share", "XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/semicolon", "XDG_RUNTIME_DIR": "/run/user/1000", "XDG_SEAT": "seat0", "XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "cinnamon", "XDG_SESSION_ID": "c1", "XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0", "XDG_SESSION_TYPE": "x11", "XDG_VTNR": "7", "XMODIFIERS": "@im=ibus", "_": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/npm", "npm_command": "test", "npm_config_cache": "/home/semicolon/.npm", "npm_config_global_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_globalconfig": "/home/semicolon/.nvm/versions/node/v24.14.0/etc/npmrc", "npm_config_init_module": "/home/semicolon/.npm-init.js", "npm_config_local_prefix": "/home/semicolon/Drip/trust-link-backend", "npm_config_node_gyp": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js", "npm_config_noproxy": "", "npm_config_npm_version": "11.9.0", "npm_config_prefix": "/home/semicolon/.nvm/versions/node/v24.14.0", "npm_config_user_agent": "npm/11.9.0 node/v24.14.0 linux x64 workspaces/false", "npm_config_userconfig": "/home/semicolon/.npmrc", "npm_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/lib/node_modules/npm/bin/npm-cli.js", "npm_lifecycle_event": "test", "npm_lifecycle_script": "jest", "npm_node_execpath": "/home/semicolon/.nvm/versions/node/v24.14.0/bin/node", "npm_package_json": "/home/semicolon/Drip/trust-link-backend/package.json", "npm_package_name": "@truestlink/trustlink-backend", "npm_package_version": "1.0.0"}}}} + + 461 | const typo = 'SAIJDXETR5B7YFPH7SUOISWVBHHSI46JLYFDCWDMEV2L46XAHASPP35X'; + 462 | + > 463 | await expect( + | ^ + 464 | buildConfigService({ + 465 | ...VALID_ENV, + 466 | SYSTEM_SIGNER_SECRET: typo, + + at expect (node_modules/expect/build/index.js:2116:15) + at Object. (src/config/config.module.spec.ts:463:13) + +FAIL test/unit/notifications.service.spec.ts + ● NotificationsService (issue #18) › notifyFunded calls SendGrid and Twilio with the funded template + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › creates a notification record for each dispatch + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › supports all escrow notification event types and stores records + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › uses vendor for funded notifications and buyer for shipped notifications + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › retries up to 3 times on transient provider failure then resolves + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › records attemptCount=1 on first-attempt success + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › records attemptCount=3 after exhausting all retries + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › records attemptCount=2 when second attempt succeeds + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › applies exponentially increasing delays between retries + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › catches provider failures and logs without throwing + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › logs HTTP response code from provider error into the notification record + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › stores null response code when provider error carries no status + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + + ● NotificationsService (issue #18) › logs response code from nested error.response.statusCode + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 41 | }; + 42 | + > 43 | const moduleRef = await Test.createTestingModule({ + | ^ + 44 | providers: [ + 45 | NotificationsService, + 46 | PrismaService, + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/notifications.service.spec.ts:43:23) + +FAIL test/unit/escrow.repository.spec.ts + ● EscrowRepository (issue #13) › finds escrows by vendor and buyer + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 8 | + 9 | beforeEach(async () => { + > 10 | const moduleRef = await Test.createTestingModule({ + | ^ + 11 | providers: [EscrowRepository, PrismaService], + 12 | }).compile(); + 13 | + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/escrow.repository.spec.ts:10:23) + + ● EscrowRepository (issue #13) › finds only shipped escrows delivered more than 48 hours ago without disputes + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 8 | + 9 | beforeEach(async () => { + > 10 | const moduleRef = await Test.createTestingModule({ + | ^ + 11 | providers: [EscrowRepository, PrismaService], + 12 | }).compile(); + 13 | + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/escrow.repository.spec.ts:10:23) + + ● EscrowRepository (issue #13) › marks auto release completion atomically + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 8 | + 9 | beforeEach(async () => { + > 10 | const moduleRef = await Test.createTestingModule({ + | ^ + 11 | providers: [EscrowRepository, PrismaService], + 12 | }).compile(); + 13 | + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 4) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/escrow.repository.spec.ts:10:23) + +FAIL test/unit/dispute.repository.spec.ts + ● DisputeRepository (issue #14) › returns open disputes only + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 10 | + 11 | beforeEach(async () => { + > 12 | const moduleRef = await Test.createTestingModule({ + | ^ + 13 | providers: [DisputeRepository, EscrowRepository, PrismaService], + 14 | }).compile(); + 15 | + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 5) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/dispute.repository.spec.ts:12:23) + + ● DisputeRepository (issue #14) › resolves the dispute and clears the escrow dispute link + + Nest can't resolve dependencies of the PrismaService (?). Please make sure that the argument String at index [0] is available in the RootTestModule module. + + Potential solutions: + - Is RootTestModule a valid NestJS module? + - If String is a provider, is it part of the current RootTestModule? + - If String is exported from a separate @Module, is that module imported within RootTestModule? + @Module({ + imports: [ /* the Module containing String */ ] + }) + + For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors + + 10 | + 11 | beforeEach(async () => { + > 12 | const moduleRef = await Test.createTestingModule({ + | ^ + 13 | providers: [DisputeRepository, EscrowRepository, PrismaService], + 14 | }).compile(); + 15 | + + at TestingInjector.lookupComponentInParentModules (node_modules/@nestjs/core/injector/injector.js:300:19) + at TestingInjector.resolveComponentWrapper (node_modules/@nestjs/testing/testing-injector.js:19:45) + at resolveParam (node_modules/@nestjs/core/injector/injector.js:150:38) + at async Promise.all (index 0) + at TestingInjector.resolveConstructorParams (node_modules/@nestjs/core/injector/injector.js:179:27) + at TestingInjector.loadInstance (node_modules/@nestjs/core/injector/injector.js:77:13) + at TestingInjector.loadProvider (node_modules/@nestjs/core/injector/injector.js:111:9) + at node_modules/@nestjs/core/injector/instance-loader.js:56:13 + at async Promise.all (index 5) + at TestingInstanceLoader.createInstancesOfProviders (node_modules/@nestjs/core/injector/instance-loader.js:55:9) + at node_modules/@nestjs/core/injector/instance-loader.js:40:13 + at async Promise.all (index 1) + at TestingInstanceLoader.createInstances (node_modules/@nestjs/core/injector/instance-loader.js:39:9) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/core/injector/instance-loader.js:22:13) + at TestingInstanceLoader.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-instance-loader.js:9:9) + at TestingModuleBuilder.createInstancesOfDependencies (node_modules/@nestjs/testing/testing-module.builder.js:119:9) + at TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:74:9) + at Object. (test/unit/dispute.repository.spec.ts:12:23) + +FAIL src/escrow/escrow.evidence-upload.spec.ts (28.029 s) + ● Evidence Upload Rate Limiting (e2e) › POST /escrow/evidence-upload › should allow requests within rate limit + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › POST /escrow/evidence-upload › should return 429 when rate limit is exceeded + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › POST /escrow/evidence-upload › should include Retry-After header in 429 response + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › POST /escrow/evidence-upload › should reset rate limit after TTL expires + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › POST /escrow/evidence-upload › should rate limit per IP (different tokens share the same IP limit) + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › POST /escrow/evidence-upload › should allow legitimate uploads within normal usage patterns + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › Environment Variable Configuration › should use default values when env vars are not set + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + ● Evidence Upload Rate Limiting (e2e) › Environment Variable Configuration › should use custom values from env vars + + thrown: "Exceeded timeout of 15000 ms for a hook. + Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." + + 19 | }; + 20 | + > 21 | beforeAll(async () => { + | ^ + 22 | const moduleFixture: TestingModule = await Test.createTestingModule({ + 23 | imports: [AppModule], + 24 | }).compile(); + + at src/escrow/escrow.evidence-upload.spec.ts:21:3 + at Object. (src/escrow/escrow.evidence-upload.spec.ts:13:1) + + +Test Suites: 6 failed, 70 passed, 76 total +Tests: 56 failed, 643 passed, 699 total +Snapshots: 0 total +Time: 46.143 s +Ran all test suites. diff --git a/typecheck.log b/typecheck.log new file mode 100644 index 00000000..2195af2b --- /dev/null +++ b/typecheck.log @@ -0,0 +1,23 @@ + +> @truestlink/trustlink-backend@1.0.0 typecheck +> tsc --noEmit + +src/admin/dispute/dto/admin-disputes-paginated-response.dto.ts(2,36): error TS2307: Cannot find module '../../escrow/dto/dispute-response.dto' or its corresponding type declarations. +src/common/dto/readiness-response.dto.ts(99,13): error TS2353: Object literal may only specify known properties, and '$ref' does not exist in type 'SchemaObjectMetadata'. +src/common/dto/readiness-response.dto.ts(100,18): error TS2353: Object literal may only specify known properties, and '$ref' does not exist in type 'SchemaObjectMetadata'. +src/config/config.module.spec.ts(2,1): error TS6133: 'NestConfigModule' is declared but its value is never read. +src/config/config.module.spec.ts(3,1): error TS6133: 'Joi' is declared but its value is never read. +src/config/config.module.spec.ts(134,48): error TS2345: Argument of type '{ SEP10_SIGNING_SECRET: undefined; DATABASE_URL: string; SEP10_JWT_SECRET: string; SYSTEM_SIGNER_SECRET: string; ADMIN_ADDRESS: string; CONTRACT_ID: string; NODE_ENV: string; STELLAR_NETWORK: string; }' is not assignable to parameter of type 'Record'. + Property 'SEP10_SIGNING_SECRET' is incompatible with index signature. + Type 'undefined' is not assignable to type 'string'. +src/config/config.module.ts(48,7): error TS6133: 'stellarPublicKey' is declared but its value is never read. +src/dlq/dlq.controller.spec.ts(211,37): error TS2345: Argument of type '{ status: string; id: string; operation: string; escrowId: string | null; errorMessage: string; ledgerFeedback: Record | null; attempts: number; createdAt: Date; updatedAt: Date; reviewedAt: Date | null; replayedAt: Date | null; lastReplayTxHash: string | null; }' is not assignable to parameter of type 'FailedTransactionRecord | Promise'. + Type '{ status: string; id: string; operation: string; escrowId: string | null; errorMessage: string; ledgerFeedback: Record | null; attempts: number; createdAt: Date; updatedAt: Date; reviewedAt: Date | null; replayedAt: Date | null; lastReplayTxHash: string | null; }' is not assignable to type 'FailedTransactionRecord'. + Types of property 'status' are incompatible. + Type 'string' is not assignable to type 'FailedTransactionStatus'. +src/escrow/escrow.repository.ts(168,26): error TS2339: Property 'count' does not exist on type '{ create: ({ data }: { data: EscrowCreateInput; }) => Promise; findUnique: ({ where, }: { where: { id: string; }; }) => Promise; ... 4 more ...; deleteMany: () => Promise<...>; }'. +src/prisma/prisma.service.ts(1,47): error TS6133: 'Optional' is declared but its value is never read. +src/vendor/analytics/analytics.service.ts(6,29): error TS2724: '"./analytics.dto"' has no exported member named 'DailyVolumeData'. Did you mean 'DailyVolumeDataDto'? +src/vendor/analytics/analytics.service.ts(9,3): error TS2724: '"./analytics-stats.dto"' has no exported member named 'TransactionStats'. Did you mean 'TransactionStatsDto'? +src/vendor/analytics/analytics.service.ts(10,3): error TS2724: '"./analytics-stats.dto"' has no exported member named 'ChannelMetrics'. Did you mean 'ChannelMetricsDto'? +src/vendor/vendor-account-details.integration-spec.ts(6,24): error TS2307: Cannot find module '../auth-helper' or its corresponding type declarations.