Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions graphql/env/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ In addition to all environment variables supported by `@pgpmjs/env`, this packag
- `FEATURES_POSTGIS` - Enable PostGIS support

### API Configuration
- `API_SCOPED_ROUTING_SCHEMA` - Schema containing the compiled `resolve_route()` resolver (production routing always resolves through it)
- `API_ROUTING_SCHEMA` - Schema containing the compiled `resolve_route()` resolver (production routing always resolves through it)
- `API_IS_PUBLIC` - Whether API is public
- `API_EXPOSED_SCHEMAS` - Comma-separated list of exposed schemas
- `API_META_SCHEMAS` - Comma-separated list of meta schemas
Expand All @@ -74,8 +74,8 @@ GraphQL defaults are provided by `@constructive-io/graphql-types`:
anonRole: 'administrator',
roleName: 'administrator',
isPublic: true,
metaSchemas: ['constructive_routing_public', 'metaschema_public', 'metaschema_modules_public'],
scopedRoutingSchema: 'constructive_routing_public'
metaSchemas: ['routing_public', 'metaschema_public', 'metaschema_modules_public'],
routingSchema: 'routing_public'
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion graphql/env/__tests__/__snapshots__/merge.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ exports[`getEnvOptions merges pgpm defaults, graphql defaults, config, env, and
"env_meta2",
],
"roleName": "env_role",
"scopedRoutingSchema": "constructive_routing_public",
"routingSchema": "routing_public",
},
"cdn": {
"awsAccessKey": "minioadmin",
Expand Down
4 changes: 2 additions & 2 deletions graphql/env/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const getGraphQLEnvVars = (env: NodeJS.ProcessEnv = process.env): Partial
FEATURES_OPPOSITE_BASE_NAMES,
FEATURES_POSTGIS,

API_SCOPED_ROUTING_SCHEMA,
API_ROUTING_SCHEMA,
API_IS_PUBLIC,
API_EXPOSED_SCHEMAS,
API_META_SCHEMAS,
Expand Down Expand Up @@ -60,7 +60,7 @@ export const getGraphQLEnvVars = (env: NodeJS.ProcessEnv = process.env): Partial
...(FEATURES_POSTGIS && { postgis: parseEnvBoolean(FEATURES_POSTGIS) })
},
api: {
...(API_SCOPED_ROUTING_SCHEMA && { scopedRoutingSchema: API_SCOPED_ROUTING_SCHEMA }),
...(API_ROUTING_SCHEMA && { routingSchema: API_ROUTING_SCHEMA }),
...(API_IS_PUBLIC && { isPublic: parseEnvBoolean(API_IS_PUBLIC) }),
...(API_EXPOSED_SCHEMAS && { exposedSchemas: API_EXPOSED_SCHEMAS.split(',').map(s => s.trim()) }),
...(API_META_SCHEMAS && { metaSchemas: API_META_SCHEMAS.split(',').map(s => s.trim()) }),
Expand Down
22 changes: 11 additions & 11 deletions graphql/playwright-test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ Constructive Playwright Testing with HTTP server support for end-to-end testing.

This package extends `@constructive-io/graphql-test` to provide an actual HTTP server for Playwright and other E2E testing frameworks. It creates isolated test databases and starts a GraphQL server for your suite to hit over HTTP.

It can run either server, selected per-suite with `server.scopedRouting`:
It can run either server, selected per-suite with `server.useRouting`:

- `server.scopedRouting: false` (default) — the single-tenant `@constructive-io/graphql-dev-server` (pure PostGraphile). No host route resolution and no database id; the configured schemas are exposed directly. Best for UI/local suites.
- `server.scopedRouting: true` — the production `@constructive-io/graphql-server`. Every request is resolved through the scoped-routing plane (`constructive_routing_public.resolve_route()`), so the suite must seed real routing/database records and reach the api surface via its seeded host (`Host` header).
- `server.useRouting: false` (default) — the single-tenant `@constructive-io/graphql-dev-server` (pure PostGraphile). No host route resolution and no database id; the configured schemas are exposed directly. Best for UI/local suites.
- `server.useRouting: true` — the production `@constructive-io/graphql-server`. Every request is resolved through the scoped-routing plane (`constructive_routing_public.resolve_route()`), so the suite must seed real routing/database records and reach the api surface via its seeded host (`Host` header).

## Installation

Expand Down Expand Up @@ -61,7 +61,7 @@ describe('E2E Tests', () => {

### Against the real (scoped-routing) server

Set `server.scopedRouting: true` to run the production `@constructive-io/graphql-server`. Seed real routing/database records and address the api surface by its seeded host:
Set `server.useRouting: true` to run the production `@constructive-io/graphql-server`. Seed real routing/database records and address the api surface by its seeded host:

```typescript
import { test, expect } from '@playwright/test';
Expand All @@ -73,9 +73,9 @@ test('resolves through the scoped routing plane', async ({ request }) => {
schemas: ['simple-pets-public'],
authRole: 'anonymous',
server: {
scopedRouting: true,
useRouting: true,
api: {
scopedRoutingSchema: 'constructive_routing_public',
routingSchema: 'constructive_routing_public',
isPublic: true,
metaSchemas: ['constructive_routing_public', 'metaschema_public']
}
Expand Down Expand Up @@ -166,8 +166,8 @@ Creates database connections and starts an HTTP server for testing.
- `input.authRole` - Default authentication role (e.g., 'anonymous', 'authenticated')
- `input.server.port` - Port to run the server on (defaults to random available port)
- `input.server.host` - Host to bind to (defaults to 'localhost')
- `input.server.scopedRouting` - `false` (default) runs the dev server; `true` runs the production scoped-routing server
- `input.server.api` - API options forwarded to the production scoped server (e.g. `metaSchemas`, `isPublic`); only used when `scopedRouting` is `true`
- `input.server.useRouting` - `false` (default) runs the dev server; `true` runs the production scoped-routing server
- `input.server.api` - API options forwarded to the production scoped server (e.g. `metaSchemas`, `isPublic`); only used when `useRouting` is `true`
- `input.graphile` - Optional Graphile configuration overrides
- `seedAdapters` - Optional array of seed adapters for database setup

Expand Down Expand Up @@ -197,18 +197,18 @@ Low-level function to create just the production `@constructive-io/graphql-serve
## How It Works

1. Creates an isolated test database using `pgsql-test`
2. Starts either the dev server or the production scoped-routing server (see `server.scopedRouting`)
2. Starts either the dev server or the production scoped-routing server (see `server.useRouting`)
3. Exposes the GraphQL endpoint for your suite to hit over HTTP
4. Returns the server URL for Playwright to connect to
5. Provides a teardown function that stops the server and cleans up the database

## Configuration

By default (`scopedRouting: false`) the server runs `@constructive-io/graphql-dev-server`, which means:
By default (`useRouting: false`) the server runs `@constructive-io/graphql-dev-server`, which means:
- No host route resolution (`resolve_route()`) is required and no database id is needed
- Schemas are exposed directly based on the `schemas` parameter
- Perfect for isolated testing without complex domain setup

With `scopedRouting: true` the server runs the production `@constructive-io/graphql-server`:
With `useRouting: true` the server runs the production `@constructive-io/graphql-server`:
- Every request is resolved through `constructive_routing_public.resolve_route()`
- The suite must seed real routing/database records and address the api surface by its seeded host
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* routing/database records and reaches the api surface via its seeded host.
*
* Contrast with `server.playwright.test.ts`, which uses the single-tenant dev
* server (`scopedRouting` defaults to `false`).
* server (`useRouting` defaults to `false`).
*/
import { expect, test } from '@playwright/test';
import path from 'path';
Expand Down Expand Up @@ -46,9 +46,9 @@ test.describe('playwright-test scoped server (real graphql-server)', () => {
schemas,
authRole: 'anonymous',
server: {
scopedRouting: true,
useRouting: true,
api: {
scopedRoutingSchema: 'constructive_routing_public',
routingSchema: 'constructive_routing_public',
isPublic: true,
metaSchemas: scopedMetaSchemas
}
Expand Down
6 changes: 3 additions & 3 deletions graphql/playwright-test/src/get-connections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ const createConnectionsWithServerBase = async (

// Start the HTTP server. Suites default to the single-tenant dev server;
// suites exercising the real routing plane opt into the production
// scoped-routing server with `server.scopedRouting: true`.
const scopedRouting = input.server?.scopedRouting ?? false;
const server = scopedRouting
// scoped-routing server with `server.useRouting: true`.
const useRouting = input.server?.useRouting ?? false;
const server = useRouting
? await createScopedTestServer(serverOpts, input.server)
: await createTestServer(serverOpts, input.server);

Expand Down
4 changes: 2 additions & 2 deletions graphql/playwright-test/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ export interface PlaywrightServerOptions {
* every request through the scoped-routing plane. Suites must seed real
* routing/database records so `resolve_route()` returns a real database id.
*/
scopedRouting?: boolean;
useRouting?: boolean;
/**
* API configuration forwarded to the production scoped server (e.g.
* `metaSchemas`, `isPublic`). Only used when `scopedRouting` is `true`.
* `metaSchemas`, `isPublic`). Only used when `useRouting` is `true`.
*/
api?: Partial<ApiOptions>;
}
Expand Down
12 changes: 6 additions & 6 deletions graphql/server-test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ The `server.api` option provides full control over the GraphQL server configurat

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `scopedRoutingSchema` | `string` | `constructive_routing_public` | Schema that owns `resolve_route()` and the routing tables |
| `routingSchema` | `string` | `routing_public` | Schema that owns `resolve_route()` and the routing tables |
| `exposedSchemas` | `string[]` | from `schemas` | Database schemas to expose (overridden by `schemas`) |
| `anonRole` | `string` | from `authRole` | Anonymous role name (overridden by `authRole`) |
| `roleName` | `string` | from `authRole` | Default role name (overridden by `authRole`) |
Expand All @@ -190,12 +190,12 @@ The `server.api` option provides full control over the GraphQL server configurat

The convenience properties (`schemas`, `authRole`) take precedence over corresponding values in `server.api`.

### Choosing the server (`server.scopedRouting`)
### Choosing the server (`server.useRouting`)

The harness runs suites against one of two servers:

- `server.scopedRouting: true` (default) — the production `@constructive-io/graphql-server`. Every request resolves through the scoped-routing plane, so the suite must seed real routing/database records and use a real database id.
- `server.scopedRouting: false` — the single-tenant `@constructive-io/graphql-dev-server` (pure PostGraphile, no routing, no database id). It exposes the configured schemas directly and is for local/static suites only.
- `server.useRouting: true` (default) — the production `@constructive-io/graphql-server`. Every request resolves through the scoped-routing plane, so the suite must seed real routing/database records and use a real database id.
- `server.useRouting: false` — the single-tenant `@constructive-io/graphql-dev-server` (pure PostGraphile, no routing, no database id). It exposes the configured schemas directly and is for local/static suites only.

```typescript
// Basic usage with convenience properties
Expand All @@ -208,7 +208,7 @@ const { query } = await getConnections({
const { query } = await getConnections({
schemas: ['app_public'],
server: {
scopedRouting: false
useRouting: false
}
});

Expand All @@ -219,7 +219,7 @@ const { query } = await getConnections({
server: {
port: 5555,
host: 'localhost',
scopedRouting: true,
useRouting: true,
api: {
isPublic: false,
metaSchemas: ['constructive_routing_public', 'metaschema_public']
Expand Down
6 changes: 3 additions & 3 deletions graphql/server-test/__tests__/cli-e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ describe('CLI E2E — generated CLI against real DB', () => {
{
schemas: ['simple-pets-pets-public'],
authRole: 'anonymous',
server: { scopedRouting: false, api: { isPublic: false } }
server: { useRouting: false, api: { isPublic: false } }
},
[
seed.sqlfile([
Expand Down Expand Up @@ -782,7 +782,7 @@ describe('CLI E2E — search commands against real DB', () => {
{
schemas: ['search_public'],
authRole: 'anonymous',
server: { scopedRouting: false, api: { isPublic: false } }
server: { useRouting: false, api: { isPublic: false } }
},
[
seed.sqlfile([
Expand Down Expand Up @@ -1126,7 +1126,7 @@ describe('CLI E2E — embedder / --auto-embed', () => {
{
schemas: ['search_public'],
authRole: 'anonymous',
server: { scopedRouting: false, api: { isPublic: false } }
server: { useRouting: false, api: { isPublic: false } }
},
[
seed.sqlfile([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,11 @@ beforeAll(async () => {
schemas,
authRole: 'anonymous',
server: {
scopedRouting: true,
useRouting: true,
api: {
isPublic: true,
metaSchemas
metaSchemas,
routingSchema: 'constructive_routing_public'
}
}
},
Expand Down
5 changes: 3 additions & 2 deletions graphql/server-test/__tests__/fn-routes.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,11 @@ beforeAll(async () => {
schemas,
authRole: 'anonymous',
server: {
scopedRouting: true,
useRouting: true,
api: {
isPublic: true,
metaSchemas
metaSchemas,
routingSchema: 'constructive_routing_public'
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion graphql/server-test/__tests__/schema-snapshot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('Schema Snapshot', () => {
schemas,
authRole: 'anonymous',
server: {
scopedRouting: false,
useRouting: false,
api: { isPublic: false }
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ describe('simple-seed-scoped: resolve_route (SQL level)', () => {
{
schemas,
authRole: 'anonymous',
server: { scopedRouting: false, api: { isPublic: false } }
server: { useRouting: false, api: { isPublic: false } }
},
scopedSeedAdapters()
));
Expand Down Expand Up @@ -174,9 +174,9 @@ describe('simple-seed-scoped: GraphQL over scoped routing (e2e)', () => {
schemas,
authRole: 'anonymous',
server: {
scopedRouting: true,
useRouting: true,
api: {
scopedRoutingSchema: 'constructive_routing_public',
routingSchema: 'constructive_routing_public',
isPublic: true,
metaSchemas: scopedMetaSchemas
}
Expand Down
2 changes: 1 addition & 1 deletion graphql/server-test/__tests__/search.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('Unified Search — server integration', () => {
schemas,
authRole: 'anonymous',
server: {
scopedRouting: false,
useRouting: false,
api: { isPublic: false }
}
},
Expand Down
4 changes: 2 additions & 2 deletions graphql/server-test/__tests__/server-test.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('graphql-server-test', () => {
schemas: ['app_public'],
authRole: 'anonymous',
server: {
scopedRouting: false
useRouting: false
}
},
[seed.sqlfile([sql('test.sql')])]
Expand Down Expand Up @@ -111,7 +111,7 @@ describe('graphql-server-test', () => {
schemas: ['app_public'],
authRole: 'authenticated',
server: {
scopedRouting: false
useRouting: false
}
},
[seed.sqlfile([sql('test.sql')])]
Expand Down
Loading
Loading