E2E Testing Guide

End-to-end tests for the Unigox Partner API. These tests run against local Docker services and validate the full request flow through the API gateway to backend services.

Prerequisites

Running Services

All services must be running via Docker on the unigox-network:

Service
Container Name
Port
Image

PostgreSQL

shared-postgres

5432

postgres:17.3

MongoDB

shared-mongodb

27017

mongo:8.0.4

Redis

shared-redis

6379

redis:8.4-alpine

Account

account

8081

account_management / account-dev

Verification

verification-service

8083

verification-service

Trades

trades-service

8085

trades-service

Escrow

escrow

8082

escrow

Currencies

currencies

8087

currencies-dev

Offers

offers

8084

offers-dev

API Gateway

api

8080

api-gateway

Start infrastructure first:

cd unigox-dev-infra && docker compose up -d

Then start services:

API Gateway Environment

The API gateway must point to local services. When creating the container, pass:

Health Checks

Test Partner Setup

Create a test partner in PostgreSQL if one doesn't exist:

Create route configs for the test partner:

Trades Service: System Settings

The trades service requires NEW_USER_MULTIPLIER_FOR_PERCENTS in system_settings. If the column name is outdated:

Known Local Environment Issues

MongoDB Database Name Mismatch

Production and staging use database verification (singular). The local verification-service .env uses verifications (plural). This means the account service (which reads from verification) won't find KYC data written by the verification service locally.

Workaround for local testing: Temporarily change the verification-service .env:

Then restart the verification-service container. Revert after testing.

Verification Service .env Inline Comments

Docker --env-file does NOT strip inline comments. If you recreate the verification-service container, inline comments like:

become part of the value (abc123 # Sandbox key). Move comments to their own line:

Node.js dotenv handles inline comments correctly, so this only matters when recreating Docker containers with --env-file.

Verification Service Volume Mount + node_modules

The verification-service image bakes in node_modules for Linux. If you volume-mount the source directory (-v ./verification-service:/usr/src/app), the host's node_modules (built for macOS) overrides the container's.

Fix: Use a separate volume for node_modules:

Then install missing native modules inside the container:

Go Services: shared-modules Private Dependency

Account and trades services depend on github.com/Unigox/shared-modules. Docker containers may not have git or GitHub credentials. If air fails to rebuild:

The account container has /shared-modules volume-mounted. For trades, copy it manually:

Switch API Not Available Locally

The Switch liquidity provider API (switch-v2.up.railway.app) requires a production API key. Local trades service can't create EUR offramp quotes or initiate trades through Switch. Test Switch-related features on staging instead, or verify via code review.

E2E Test Cases

All tests use:

Test 1: User Creation + KYC with Address Fields

Tests: account service user creation, verification service direct_data KYC, auto-verify flow.

Expected results:

  • User created with user_uuid and kyc_status: NOT_INITIATED

  • KYC submission returns success: true

  • Verification status becomes VERIFIED (direct_data auto-verify)

  • AiPrise async AML screening fires in background (may fail locally with sandbox key, not blocking)

Payload structure note: The KYC endpoint expects { method, data: { pii: { ... } } } — the PII fields are nested under data.pii, not directly under data.

Test 2: PATCH /kyc to Update Optional PII

Tests: updating address/city/postal_code on an existing verified user without re-triggering verification.

Expected results:

  • PATCH returns success: true with updated_fields: ["address", "city", "postal_code", "phone_number"]

  • Verification status stays VERIFIED

  • MongoDB KycData has address, city, postalCode, phoneNumber at top level

Verify MongoDB:

Note: MongoDB userId is the internal integer ID (as string), not the public UUID. Look up with:

Test 3: Payment Details Auto-Populate from KYC

Tests: account service auto-populates holder_city/holder_street/holder_postal_code from KYC data when creating EUR payment details.

Prerequisite: User must have address/city/postal_code in KYC (from Test 2). Also requires the MongoDB database name workaround (see Known Issues above).

Expected results:

  • Payment details created with payment_details_id

  • Database details JSONB contains holder_city, holder_street, holder_postal_code auto-populated from KYC

  • Response details only shows iban and full_name (auto-populated fields are not in the response, only in DB)

Verify in PostgreSQL:

Common failures:

  • "invalid rail" — partner_route_config missing for the test partner (see Setup section)

  • "Invalid JSON payload" — missing required field rail in request body

  • Auto-populate doesn't fire — MongoDB database name mismatch (see Known Issues)

  • Full name validation error — full_name must be 2-50 chars, letters/spaces/hyphens/apostrophes only

Test 4: EUR Offramp Order with action_required

Tests: trades service returns action_required in order response when address is missing for EUR/AUD/GBP offramp.

Note: This test requires Switch API access or pre-created trade data. Locally, Switch returns 401. To test, insert trade data directly:

If a trade exists in trade_created status with partner_details_checked_at IS NULL, trade_type = 'SELL', and fiat_currency_code = 'EUR':

Expected response includes:

Test 5: Switch EUR Country Whitelist

Tests: Switch offers are excluded for unsupported EUR countries (e.g. Cyprus).

This is a code-level test — the SwitchSupportsEurCountry function in trades/internal/service/trade_request/providers/provider_switch.go filters offers during matching. No live API needed.

If no unit test exists, verify by reading the code:

  • switchEurSupportedCountries list: 35 European countries

  • CY (Cyprus) is NOT in the list

  • LT (Lithuania) IS in the list

  • Only filters EUR + SELL (offramp). BUY (onramp) is not filtered.

  • When countryCode is empty, falls back to IBAN prefix (first 2 chars)

Test 6: Regression — Existing Flows

Basic smoke tests to verify existing functionality isn't broken.

Debugging Tips

Service Logs

MongoDB Queries

PostgreSQL Queries

API Gateway Path Transformations

The API gateway transforms paths before proxying to backend services:

Gateway Path
Backend Path
Service

/partner/users/{id}/kyc-submissions

/partner/kyc-submissions/{id}

verification

/partner/users/{id}/verification-status

/partner/verification-status/{id}

verification

/partner/users/{id}/kyc/documents

/partner/{id}/kyc/documents

verification

/partner/users/{id}/kyc

/partner/users/{id}/kyc

verification (no transform)

/partner/users/*

/api/v1/partner/users/*

account (prefixed)

/partner/orders/*

/api/v1/partner/orders/*

trades (prefixed)

Last updated