# Integration Tests `integration` owns only true inter-service black-box tests. Each suite must raise real service processes, speak only over public HTTP/gRPC/Redis contracts, and avoid imports from `internal/...` packages of tested services. ## Layout ```text integration/ ├── README.md ├── authsessionmail/ │ ├── authsession_mail_test.go │ └── harness_test.go ├── gatewayauthsessionmail/ │ ├── gateway_authsession_mail_test.go │ └── harness_test.go ├── gatewayauthsessionusermail/ │ └── gateway_authsession_user_mail_test.go ├── authsessionuser/ │ ├── authsession_user_test.go │ └── harness_test.go ├── gatewayauthsession/ │ ├── harness_test.go │ └── gateway_authsession_test.go ├── gatewayauthsessionuser/ │ ├── gateway_authsession_user_test.go │ └── harness_test.go ├── gatewayuser/ │ ├── gateway_user_test.go │ └── harness_test.go ├── notificationgateway/ │ └── notification_gateway_test.go ├── notificationmail/ │ └── notification_mail_test.go ├── notificationuser/ │ └── notification_user_test.go ├── lobbyuser/ │ └── lobby_user_test.go ├── lobbynotification/ │ ├── lobby_notification_test.go │ └── race_name_intents_test.go ├── go.mod ├── go.sum └── internal/ ├── contracts/ │ ├── gatewayv1/ │ │ └── contract.go │ └── userv1/ │ └── contract.go └── harness/ ├── binary.go ├── keys.go ├── mail_stub.go ├── process.go ├── redis_container.go ├── smtp_capture.go └── user_stub.go ``` ## Rules - Keep suites black-box. Do not import `galaxy/gateway/internal/...`, `galaxy/authsession/internal/...`, or any other service-owned internal package. - Start real binaries from `cmd/...` and talk to them only through their published HTTP, gRPC, and Redis contracts. - Put boundary-specific orchestration and assertions into the owning suite package, not into shared helpers. - Put only generic process/runtime utilities into `internal/harness`. - Put only public-contract helpers into `internal/contracts/...`. ## Current Boundary Suites - `gatewayauthsession` verifies the integration boundary between real `Edge Gateway` and real `Auth / Session Service`. - `authsessionuser` verifies the integration boundary between real `Auth / Session Service` and real `User Service`. - `authsessionmail` verifies the integration boundary between real `Auth / Session Service` and real `Mail Service`. - `gatewayauthsessionmail` verifies the public auth flow across real `Edge Gateway`, real `Auth / Session Service`, and real `Mail Service`. - `gatewayuser` verifies the direct authenticated self-service boundary between real `Edge Gateway` and real `User Service`. - `gatewayauthsessionuser` verifies the full public-auth plus authenticated-account chain across real `Edge Gateway`, real `Auth / Session Service`, and real `User Service`. - `notificationgateway` verifies that real `Notification Service` push publication is consumed and fanned out by real `Edge Gateway` for all user-facing push types. - `notificationmail` verifies that real `Notification Service` template-mode mail publication is consumed by real `Mail Service` for all notification email types. - `notificationuser` verifies that real `Notification Service` enriches recipients through real `User Service` and preserves Redis stream progress semantics for missing or temporarily unavailable users. - `gatewayauthsessionusermail` verifies the full public registration chain across real `Edge Gateway`, real `Auth / Session Service`, real `User Service`, and real `Mail Service`, including the regression that auth-code mail bypasses `notification:intents`. - `lobbyuser` verifies the synchronous eligibility boundary between real `Game Lobby` and real `User Service`, including the happy path, permanent_block rejection, unknown user, and transient User Service unavailability. - `lobbynotification` verifies the producer side of `Game Lobby → notification:intents`, covering all eleven `lobby.*` intent types from applications, invites, member operations, runtime pause, cascade membership block, and the three race-name intents emitted by capability evaluation at game finish and by self-service registration. The current fast suites still use one isolated `miniredis` instance plus either real downstream processes or external stateful HTTP stubs where appropriate. `authsessionmail`, `gatewayauthsessionmail`, `notificationgateway`, `notificationmail`, `notificationuser`, `gatewayauthsessionusermail`, `lobbyuser`, and `lobbynotification` are the deliberate exceptions: they use one real Redis container through `testcontainers-go`, because those boundaries must exercise real Redis stream, persistence, or scheduling behavior. `authsessionmail` additionally contains one targeted SMTP-capture scenario for the real `smtp` provider path, while `gatewayauthsessionmail` keeps `Mail Service` in `stub` mode and extracts the confirmation code through the trusted operator delivery surface. ## Running Run from the module directory: ```bash cd integration go test ./gatewayauthsession/... go test ./authsessionuser/... go test ./authsessionmail/... go test ./gatewayauthsessionmail/... go test ./gatewayuser/... go test ./gatewayauthsessionuser/... go test ./notificationgateway/... go test ./notificationmail/... go test ./notificationuser/... go test ./gatewayauthsessionusermail/... go test ./lobbyuser/... go test ./lobbynotification/... ``` Useful regression commands after boundary changes: ```bash go test ./gatewayauthsession/... go test ./authsessionuser/... go test ./authsessionmail/... go test ./gatewayauthsessionmail/... go test ./gatewayuser/... go test ./gatewayauthsessionuser/... go test ./notificationgateway/... go test ./notificationmail/... go test ./notificationuser/... go test ./gatewayauthsessionusermail/... go test ./lobbyuser/... go test ./lobbynotification/... cd ../gateway && go test ./... cd ../authsession && go test ./... -run GatewayCompatibility cd ../user && go test ./... ``` Do not use `go test ./...` from the repository root. The repository is organized through `go.work`, so verification should stay module-scoped. ## Adding A New Boundary Suite 1. Create `integration//` for the new inter-service boundary. 2. Keep suite-local fixtures, scenario helpers, and assertion helpers inside that package. 3. Reuse `internal/harness` only for generic concerns such as binary build/run, ports, keys, Redis, and shared external stubs. 4. Add new helpers to `internal/contracts//` only when they describe a reusable public wire contract. 5. Prefer fast deterministic infrastructure by default: in-memory test doubles, `httptest` stubs, and `miniredis`. ## Real Redis Suites Fast suites stay on `miniredis` by default. When one boundary explicitly needs real Redis semantics, prefer a package-local container setup through `testcontainers-go` plus reusable helpers in `internal/harness`, as done by `authsessionmail` and `gatewayauthsessionmail`. Current rule of thumb: - use `miniredis` when the boundary does not depend on Redis persistence or scheduling behavior - use `testcontainers-go` only when the real Redis process materially changes the behavior being verified