From a86b850a4af7fbeffb4415e305c6457b7a3ce2cd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Sep 2025 10:18:45 +0000 Subject: [PATCH 1/4] Initial plan From a51567eb2832f3132c2142f9ec1e214b0ec7adc3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Sep 2025 10:29:45 +0000 Subject: [PATCH 2/4] Add documentation for first 5 test suites with detailed comments and READMEs Co-authored-by: kamilkisiela <8167190+kamilkisiela@users.noreply.github.com> --- .../interface-object-with-requires/README.md | 52 ++++++++++ .../interface-object-with-requires/test.ts | 31 ++++++ src/test-suites/mutations/README.md | 41 ++++++++ src/test-suites/mutations/test.ts | 23 ++++- src/test-suites/simple-entity-call/README.md | 31 ++++++ src/test-suites/simple-entity-call/test.ts | 5 + .../simple-requires-provides/README.md | 98 +++++++++++++++++++ .../simple-requires-provides/test.ts | 46 +++++++++ src/test-suites/typename/README.md | 67 +++++++++++++ src/test-suites/typename/test.ts | 28 ++++++ 10 files changed, 418 insertions(+), 4 deletions(-) create mode 100644 src/test-suites/interface-object-with-requires/README.md create mode 100644 src/test-suites/mutations/README.md create mode 100644 src/test-suites/simple-entity-call/README.md create mode 100644 src/test-suites/simple-requires-provides/README.md create mode 100644 src/test-suites/typename/README.md diff --git a/src/test-suites/interface-object-with-requires/README.md b/src/test-suites/interface-object-with-requires/README.md new file mode 100644 index 00000000..79d33343 --- /dev/null +++ b/src/test-suites/interface-object-with-requires/README.md @@ -0,0 +1,52 @@ +# Interface Object with Requires + +## Overview +This test suite validates the `@interfaceObject` directive combined with the `@requires` directive in Apollo Federation, testing how interface objects can depend on fields from other subgraphs. + +## Apollo Federation Concepts Tested +- **@interfaceObject directive**: Converting interfaces into objects that can be extended across subgraphs +- **@requires directive**: Fields that depend on other fields from different subgraphs +- **@external directive**: Fields owned by other subgraphs +- **Interface vs concrete type resolution**: How the gateway handles both interface objects and concrete implementations +- **Inline fragments**: Accessing concrete type fields through interface queries + +## Test Scenario +The test involves a `NodeWithName` interface that is distributed across two subgraphs: + +1. **Subgraph A**: + - Defines `NodeWithName` interface and `User` concrete type + - Owns the `User` entity with `id`, `name`, and `age` fields + - Provides `users` query returning concrete User types + +2. **Subgraph B**: + - Uses `@interfaceObject` to create an object version of `NodeWithName` interface + - Marks `name` as `@external` (owned by subgraph A) + - Defines `username` field with `@requires(fields: "name")` + - Provides `anotherUsers` query returning interface objects + +## Test Cases + +### 1. Basic Interface Object Resolution with @requires +- Tests that interface objects can resolve fields that require external dependencies +- Verifies `username` field is correctly computed using the required `name` field + +### 2. Standard Entity Resolution +- Compares interface object behavior with standard entity resolution +- Ensures both patterns work correctly and produce consistent results + +### 3. Inline Fragment Resolution +- Tests that `... on User` fragments work with both interface objects and concrete types +- Verifies access to concrete type fields (`age`) through interface queries + +### 4. Complex Field Selection +- Tests queries that select both interface fields and concrete type fields +- Verifies the gateway can handle mixed field selections correctly + +## What's Being Tested +1. **Interface Object Extension**: `@interfaceObject` allows treating interfaces as extendable entities +2. **Cross-Subgraph Dependencies**: Fields in interface objects can depend on fields from other subgraphs +3. **Field Resolution Consistency**: Both interface objects and concrete types resolve fields consistently +4. **Fragment Handling**: Inline fragments work correctly with interface objects +5. **Complex Selection Sets**: The gateway properly handles queries with mixed field types + +This suite ensures that the advanced `@interfaceObject` directive works correctly with field dependencies, enabling powerful interface-based federation patterns. \ No newline at end of file diff --git a/src/test-suites/interface-object-with-requires/test.ts b/src/test-suites/interface-object-with-requires/test.ts index 2a216b89..fbf88288 100644 --- a/src/test-suites/interface-object-with-requires/test.ts +++ b/src/test-suites/interface-object-with-requires/test.ts @@ -1,6 +1,11 @@ import { createTest } from "../../testkit.js"; export default [ + // Test @interfaceObject with @requires directive + // Verifies that an interface object can require fields from other subgraphs + // - anotherUsers query returns NodeWithName interface objects + // - username field requires the "name" field from subgraph A + // - Tests that @interfaceObject directive works with field dependencies createTest( /* GraphQL */ ` query { @@ -28,6 +33,10 @@ export default [ }, }, ), + // Test standard User entity resolution from subgraph A + // Verifies that the concrete User type can be resolved normally + // - users query returns User entities with all fields + // - username field is resolved via entity resolution to subgraph B createTest( /* GraphQL */ ` query { @@ -55,6 +64,11 @@ export default [ }, }, ), + // Test interface object inline fragment resolution + // Verifies that inline fragments work with @interfaceObject + // - anotherUsers query returns NodeWithName interface objects + // - ... on User inline fragment accesses concrete type fields + // - age field is only available on the concrete User type from subgraph A createTest( /* GraphQL */ ` query { @@ -78,6 +92,10 @@ export default [ }, }, ), + // Test inline fragments with standard entity resolution + // Verifies that inline fragments work with regular entity types + // - users query with inline fragment on User type + // - Tests the same pattern as above but from subgraph A perspective createTest( /* GraphQL */ ` query { @@ -101,6 +119,11 @@ export default [ }, }, ), + // Test complex field selection with interface objects and inline fragments + // Verifies that both interface fields and concrete type fields can be selected + // - anotherUsers returns interface objects + // - Selects both interface fields (id, name) and concrete fields via inline fragment + // - Demonstrates full field resolution across subgraphs with @interfaceObject createTest( /* GraphQL */ ` query { @@ -135,6 +158,10 @@ export default [ }, }, ), + // Test complex field selection with standard entities and inline fragments + // Verifies the same complex selection pattern with regular entity resolution + // - users query with both direct fields and inline fragment fields + // - Demonstrates standard entity resolution behavior for comparison createTest( /* GraphQL */ ` query { @@ -169,6 +196,10 @@ export default [ }, }, ), + // Test duplicate complex field selection (edge case) + // Verifies that duplicate field selections don't cause issues + // - Same query as above but duplicated to test edge case handling + // - Ensures the gateway handles redundant field selections correctly createTest( /* GraphQL */ ` query { diff --git a/src/test-suites/mutations/README.md b/src/test-suites/mutations/README.md new file mode 100644 index 00000000..8eb39d39 --- /dev/null +++ b/src/test-suites/mutations/README.md @@ -0,0 +1,41 @@ +# Mutations + +## Overview +This test suite validates Apollo Federation's support for mutations across multiple subgraphs, including mutation ordering, shared mutations, and entity resolution within mutation responses. + +## Apollo Federation Concepts Tested +- **Cross-subgraph mutations**: Mutations that affect data in one subgraph and resolve fields from others +- **@requires directive**: Fields that depend on other fields from different subgraphs +- **@shareable directive**: Mutations that can be defined in multiple subgraphs +- **@external directive**: Fields owned by other subgraphs +- **Mutation ordering**: Sequential execution of mutations to maintain consistency +- **Entity resolution in mutations**: Resolving entity fields after mutation operations + +## Test Scenarios + +### 1. Product Creation with Cross-Subgraph Resolution +- **Subgraph A**: Defines `addProduct` mutation, owns `Product` entity with `name` and `price` +- **Subgraph B**: Extends `Product` with computed fields (`isExpensive`, `isAvailable`) +- **Test**: Verifies that after creating a product, all fields are resolved correctly + +### 2. Entity Resolution for Existing Data +- Tests that entity resolution works for querying existing products +- Validates `@requires(fields: "price")` for computing `isExpensive` field + +### 3. Sequential Mutation Execution +- **Subgraphs A, B, C**: Each provides different mathematical operations +- **Test**: Verifies mutations execute in sequence: add(5) → multiply(2) → add(2) → delete() +- Demonstrates that mutations maintain state consistency across requests + +### 4. Shared Mutations (@shareable) +- **Subgraphs A & B**: Both define `addCategory` mutation with `@shareable` +- **Test**: Verifies that the gateway can correctly route shared mutations + +## What's Being Tested +1. **Mutation Response Entity Resolution**: After a mutation, the gateway can resolve entity fields from multiple subgraphs +2. **Field Dependencies**: Fields marked with `@requires` are properly resolved with their dependencies +3. **Mutation Ordering**: Multiple mutations in a single request execute in the specified order +4. **Shared Mutation Routing**: Mutations marked as `@shareable` can be handled by multiple subgraphs +5. **State Management**: Mutations properly maintain and modify shared state across subgraphs + +This suite ensures that complex mutation scenarios work correctly in a federated environment. \ No newline at end of file diff --git a/src/test-suites/mutations/test.ts b/src/test-suites/mutations/test.ts index 9cb76d41..7bf9f49e 100644 --- a/src/test-suites/mutations/test.ts +++ b/src/test-suites/mutations/test.ts @@ -4,6 +4,11 @@ export default () => { const randomId = Math.random().toString(16).substr(2); return [ + // Test mutations that modify data and resolve entity fields across subgraphs + // Verifies that a product can be added and its computed fields are resolved correctly + // - addProduct mutation creates a new product in subgraph A + // - isExpensive field is computed in subgraph B using @requires(fields: "price") + // - isAvailable field is provided by subgraph B createTest( /* GraphQL */ ` mutation { @@ -26,6 +31,11 @@ export default () => { }, }, ), + // Test querying existing products with cross-subgraph field resolution + // Verifies that entity resolution works correctly for existing data + // - product query fetches from subgraph A (name, price) + // - isExpensive computed in subgraph B using @requires(fields: "price") + // - isAvailable provided by subgraph B createTest( /* GraphQL */ ` query { @@ -50,9 +60,11 @@ export default () => { }, }, ), - // Test correct order of execution - // It obviously does not solve a problem with shared state and race conditions, - // but at least it reduces the risk a bit + // Test correct order of execution for sequential mutations + // Verifies that mutations execute in the specified order across subgraphs + // This tests mutation sequencing to maintain data consistency + // - add(5) -> 5, multiply(2) -> 10, add(2) -> 12, delete() -> 12 + // It demonstrates that mutations with shared state execute in sequence createTest( /* GraphQL */ ` mutation { @@ -71,7 +83,10 @@ export default () => { }, }, ), - // shared-root (mutation) + // Test @shareable mutations across multiple subgraphs + // Verifies that the same mutation can be defined in multiple subgraphs + // and the gateway correctly routes to the appropriate implementation + // - addCategory is marked @shareable in both subgraphs A and B createTest( /* GraphQL */ ` mutation { diff --git a/src/test-suites/simple-entity-call/README.md b/src/test-suites/simple-entity-call/README.md new file mode 100644 index 00000000..0901a01a --- /dev/null +++ b/src/test-suites/simple-entity-call/README.md @@ -0,0 +1,31 @@ +# Simple Entity Call + +## Overview +This test suite validates the basic Apollo Federation capability of entity resolution across multiple subgraphs. + +## Apollo Federation Concepts Tested +- **Entity Resolution**: Tests the fundamental ability to resolve entities across subgraphs +- **@key directive**: Uses different key fields (`id` and `email`) to identify the same entity +- **@external directive**: Tests marking fields as external when they're owned by another subgraph + +## Test Scenario +The test involves a `User` entity that is distributed across two subgraphs: + +1. **Email Subgraph**: + - Owns the `User` entity with `@key(fields: "id")` + - Provides the main query entry point and the `email` field + - Can resolve users by their `id` + +2. **Nickname Subgraph**: + - Extends the `User` entity with `@key(fields: "email")` + - Marks `email` as `@external` since it's owned by the email subgraph + - Provides the `nickname` field + - Can resolve users by their `email` + +## What's Being Tested +The test verifies that when querying for a user's `id` and `nickname`, the gateway: +1. Fetches the user from the email subgraph (getting `id` and `email`) +2. Uses the `email` to resolve the `nickname` from the nickname subgraph +3. Combines both pieces of data into a single response + +This demonstrates the core federation principle of distributed data composition. \ No newline at end of file diff --git a/src/test-suites/simple-entity-call/test.ts b/src/test-suites/simple-entity-call/test.ts index 1a6d3f95..8ed52949 100644 --- a/src/test-suites/simple-entity-call/test.ts +++ b/src/test-suites/simple-entity-call/test.ts @@ -2,6 +2,11 @@ import { createTest } from "../../testkit.js"; import { users } from "./data.js"; export default [ + // Test basic entity resolution across subgraphs + // Verifies that a User entity can be resolved by fetching data from multiple subgraphs: + // - The 'email' subgraph provides the user query and id field + // - The 'nickname' subgraph provides the nickname field using @external email as key + // This tests the fundamental Apollo Federation capability of entity resolution createTest( /* GraphQL */ ` query { diff --git a/src/test-suites/simple-requires-provides/README.md b/src/test-suites/simple-requires-provides/README.md new file mode 100644 index 00000000..cf90ca6f --- /dev/null +++ b/src/test-suites/simple-requires-provides/README.md @@ -0,0 +1,98 @@ +# Simple Requires Provides + +## Overview +This is one of the most comprehensive test suites that validates the core Apollo Federation directives `@requires` and `@provides`. It demonstrates how these directives optimize federated queries by reducing round trips and enabling computed fields that depend on data from other subgraphs. + +## Apollo Federation Concepts Tested +- **@requires directive**: Fields that depend on other fields from different subgraphs +- **@provides directive**: Fields that can be provided by one subgraph to avoid fetching from another +- **@external directive**: Fields owned by other subgraphs +- **@shareable directive**: Fields that can be resolved by multiple subgraphs +- **Entity resolution**: Complex multi-hop entity relationships +- **Query optimization**: How requires/provides reduce network round trips + +## Test Scenario +This test suite models a typical e-commerce scenario with four subgraphs: + +### 1. Accounts Subgraph +- Owns `User` entity with `id`, `name`, `username` fields +- Provides `me` query for user authentication +- `username` is marked as `@shareable` + +### 2. Products Subgraph +- Owns `Product` entity with `upc`, `name`, `price`, `weight` fields +- Provides `products` query +- Core product information + +### 3. Reviews Subgraph +- Owns `Review` entity linking users and products +- Extends `User` with `reviews` field +- Extends `Product` with `reviews` field +- **Key feature**: Uses `@provides(fields: "username")` on `Review.author` +- This means when resolving a review's author, it provides the username field directly instead of requiring a fetch from the accounts subgraph + +### 4. Inventory Subgraph +- Extends `Product` with inventory-related fields +- Marks `price` and `weight` as `@external` +- **Key features**: + - `shippingEstimate` uses `@requires(fields: "price weight")` + - `shippingEstimateTag` uses `@requires(fields: "price weight")` + - These computed fields need the price and weight from products subgraph + +## Test Cases + +### Basic Queries (Tests 1-3) +- Simple field access without cross-subgraph dependencies +- Basic entity resolution (user -> reviews) +- **@provides demonstration**: Review author username provided directly + +### Product Queries (Tests 4-7) +- Basic product field access +- **@requires demonstration**: `shippingEstimate` computed using required fields +- Verification that required fields and computed fields can be returned together + +### Complex Scenarios (Tests 8-13) +- **Combined @provides and @requires**: Complex queries using both directives +- **Circular references**: Entities referencing each other (user -> reviews -> product -> reviews) +- **Entity chains**: Multiple entity resolutions in sequence +- **Multiple @requires fields**: Several computed fields with same dependencies + +## Query Optimization Patterns + +### Without @provides: +``` +Query: reviews { author { username } } +1. Fetch reviews from reviews subgraph +2. Fetch user data from accounts subgraph for each author +Total: 1 + N requests +``` + +### With @provides: +``` +Query: reviews { author { username } } +1. Fetch reviews with provided username from reviews subgraph +Total: 1 request +``` + +### Without @requires: +``` +Query: product { shippingEstimate } +❌ Cannot compute - price/weight not available +``` + +### With @requires: +``` +Query: product { shippingEstimate } +1. Fetch product with price/weight from products subgraph +2. Compute shippingEstimate in inventory subgraph +Total: Efficient field resolution +``` + +## What's Being Tested +1. **Field Dependencies**: `@requires` correctly fetches dependent fields before computation +2. **Query Optimization**: `@provides` reduces unnecessary subgraph calls +3. **Complex Scenarios**: Both directives work in nested, multi-entity queries +4. **Performance**: Efficient resolution of complex federated queries +5. **Correctness**: All computed and provided fields return accurate results + +This test suite is essential for validating that gateways can handle real-world federated architectures with complex data dependencies and optimization requirements. \ No newline at end of file diff --git a/src/test-suites/simple-requires-provides/test.ts b/src/test-suites/simple-requires-provides/test.ts index 06bbf5c0..b5870211 100644 --- a/src/test-suites/simple-requires-provides/test.ts +++ b/src/test-suites/simple-requires-provides/test.ts @@ -1,6 +1,8 @@ import { createTest } from "../../testkit.js"; export default [ + // Test basic user query without any cross-subgraph resolution + // Verifies simple field access from the accounts subgraph createTest( /* GraphQL */ ` query { @@ -17,6 +19,10 @@ export default [ }, }, ), + // Test basic entity resolution across subgraphs + // Verifies that user reviews can be resolved from the reviews subgraph + // - me query from accounts subgraph + // - reviews field resolved through User entity key in reviews subgraph createTest( /* GraphQL */ ` query { @@ -44,6 +50,11 @@ export default [ }, }, ), + // Test @provides directive functionality + // Verifies that the reviews subgraph can provide the username field + // - Review.author field uses @provides(fields: "username") + // - This avoids an extra round-trip to the accounts subgraph for username + // - Tests that provided fields are correctly included in the response createTest( /* GraphQL */ ` query { @@ -90,6 +101,8 @@ export default [ }, }, ), + // Test basic product name query from products subgraph + // Verifies simple field access without cross-subgraph dependencies createTest( /* GraphQL */ ` query { @@ -111,6 +124,8 @@ export default [ }, }, ), + // Test basic product price query from products subgraph + // Verifies access to price field without dependencies createTest( /* GraphQL */ ` query { @@ -132,6 +147,11 @@ export default [ }, }, ), + // Test @requires directive functionality + // Verifies that shippingEstimate field can be computed using required fields + // - shippingEstimate field in inventory subgraph uses @requires(fields: "price weight") + // - Gateway must fetch price and weight from products subgraph first + // - Then resolve shippingEstimate using those values (price * weight * 10) createTest( /* GraphQL */ ` query { @@ -153,6 +173,10 @@ export default [ }, }, ), + // Test @requires directive with multiple fields in response + // Verifies that both required fields and computed fields are returned correctly + // - Demonstrates that the gateway includes all requested fields + // - Shows the dependency resolution working alongside other field resolution createTest( /* GraphQL */ ` query { @@ -180,6 +204,12 @@ export default [ }, }, ), + // Test complex query combining @provides and @requires directives + // Verifies that both directives work together in a complex nested query + // - Products -> reviews (entity resolution) + // - Review.author.username provided by reviews subgraph (@provides) + // - Review.product.shippingEstimate requires price/weight (@requires) + // This demonstrates the full power of requires/provides optimization createTest( /* GraphQL */ ` { @@ -232,6 +262,10 @@ export default [ }, }, ), + // Test circular entity references + // Verifies that entities can reference each other without infinite loops + // - User -> reviews -> product -> reviews (circular reference) + // Tests the gateway's ability to handle complex entity relationships createTest( /* GraphQL */ ` { @@ -273,6 +307,10 @@ export default [ }, }, ), + // Test entity resolution from user through product chain + // Verifies that product fields can be resolved through user reviews + // - me.reviews.product.inStock requires multiple entity resolutions + // Tests the gateway's ability to chain entity resolutions efficiently createTest( /* GraphQL */ ` query { @@ -304,6 +342,10 @@ export default [ }, }, ), + // Test @requires directive through entity chain + // Verifies that @requires works when accessed through multiple entity resolutions + // - me.reviews.product.shippingEstimate requires price/weight through entity chain + // This is the most complex test combining entity resolution with field dependencies createTest( /* GraphQL */ ` query { @@ -335,6 +377,10 @@ export default [ }, }, ), + // Test multiple @requires fields in complex query + // Verifies that multiple computed fields can be resolved simultaneously + // - shippingEstimate and shippingEstimateTag both use @requires(fields: "price weight") + // Tests that the gateway efficiently handles multiple field dependencies createTest( /* GraphQL */ ` query { diff --git a/src/test-suites/typename/README.md b/src/test-suites/typename/README.md new file mode 100644 index 00000000..e4a16d8d --- /dev/null +++ b/src/test-suites/typename/README.md @@ -0,0 +1,67 @@ +# Typename + +## Overview +This test suite validates that the `__typename` introspection field works correctly across different GraphQL type constructs in a federated environment, including unions, interfaces, and regular entity types. + +## Apollo Federation Concepts Tested +- **`__typename` introspection**: The built-in field that returns the concrete type name +- **Union type resolution**: How `__typename` identifies concrete types in unions +- **Interface type resolution**: How `__typename` works with interface implementations +- **Entity type resolution**: How `__typename` behaves with federated entities +- **Inline fragments**: Using `__typename` within type-specific fragments +- **Field aliases**: Using aliases for `__typename` field + +## Test Scenario +The test involves several types that demonstrate different aspects of type resolution: + +1. **Union Type**: A union that can return different concrete types (Oven, Toaster) +2. **Interface Type**: An interface with concrete implementations +3. **Entity Types**: Regular federated entities (Admin users) + +## Test Cases + +### 1. Union Type `__typename` Resolution +- Tests that `__typename` correctly identifies the concrete type returned by a union field +- Verifies both direct `__typename` access and aliased versions +- Demonstrates that the gateway properly resolves union member types + +### 2. Interface Type `__typename` Resolution +- Tests that `__typename` returns the concrete implementing type, not the interface name +- Validates multiple aliases for the same `__typename` field +- Ensures interface type resolution works in federated scenarios + +### 3. Inline Fragments with `__typename` +- Tests `__typename` behavior when used within inline fragments +- Verifies that fragment-based queries correctly resolve type information +- Demonstrates conditional field selection based on concrete types + +### 4. Entity Type `__typename` Resolution +- Tests `__typename` with standard federated entities +- Compares behavior between simple entity queries and `__typename` queries +- Validates that entity types return correct type names + +## What's Being Tested + +### Type System Correctness +1. **Union Resolution**: `__typename` accurately identifies which union member is returned +2. **Interface Resolution**: `__typename` returns concrete type names, not interface names +3. **Entity Resolution**: Regular federated entities maintain correct type information + +### Federation-Specific Behavior +1. **Cross-Subgraph Types**: `__typename` works correctly for types distributed across subgraphs +2. **Gateway Type Merging**: The gateway properly maintains type information during schema composition +3. **Query Planning**: `__typename` doesn't interfere with efficient query planning + +### GraphQL Specification Compliance +1. **Field Aliases**: `__typename` can be aliased like any other field +2. **Fragment Compatibility**: `__typename` works within inline fragments +3. **Introspection Standards**: Follows GraphQL introspection specifications + +## Why This Matters +The `__typename` field is crucial for: +- **Client-side caching**: Many GraphQL clients use `__typename` for cache normalization +- **Conditional rendering**: Frontend applications often render different components based on type +- **Type guards**: Runtime type checking in strongly-typed applications +- **Debugging**: Understanding what types are actually returned by queries + +This test suite ensures that federated schemas maintain the same `__typename` behavior as monolithic schemas, preserving compatibility with existing GraphQL tooling and client applications. \ No newline at end of file diff --git a/src/test-suites/typename/test.ts b/src/test-suites/typename/test.ts index d1bbd06d..f5ecc2d8 100644 --- a/src/test-suites/typename/test.ts +++ b/src/test-suites/typename/test.ts @@ -1,6 +1,11 @@ import { createTest } from "../../testkit.js"; export default [ + // Test __typename resolution in union types + // Verifies that the __typename field correctly identifies concrete types in unions + // - union query returns different concrete types (Oven) + // - __typename field should return the correct concrete type name + // - Tests both direct __typename and aliased typename fields createTest( /* GraphQL */ ` query { @@ -19,6 +24,11 @@ export default [ }, }, ), + // Test __typename resolution in interface types + // Verifies that __typename works correctly with interface types + // - interface query returns concrete types implementing the interface + // - __typename should return the concrete type name (Toaster), not the interface name + // - Tests multiple __typename field aliases in the same query createTest( /* GraphQL */ ` query { @@ -41,6 +51,11 @@ export default [ }, }, ), + // Test __typename in union type with inline fragments + // Verifies that __typename resolution works within inline fragments + // - union query with inline fragments for different concrete types + // - __typename accessed both directly and within fragments + // - Tests fragment-based type resolution patterns createTest( /* GraphQL */ ` query { @@ -64,6 +79,10 @@ export default [ }, }, ), + // Test __typename in interface type with inline fragments + // Verifies that __typename works correctly in interface queries with fragments + // - interface query with fragments for concrete implementing types + // - Demonstrates proper type resolution in federated interface scenarios createTest( /* GraphQL */ ` query { @@ -87,6 +106,10 @@ export default [ }, }, ), + // Test basic entity resolution without __typename + // Verifies normal entity resolution works alongside __typename tests + // - users query returns simple entity data + // - Provides baseline for comparing with __typename behavior createTest( /* GraphQL */ ` query { @@ -108,6 +131,11 @@ export default [ }, }, ), + // Test __typename with regular entity types + // Verifies that __typename works correctly with standard federated entities + // - users query returns entities with their concrete type name + // - In this case, all users are "Admin" type + // - Tests __typename behavior in entity-based federation scenarios createTest( /* GraphQL */ ` query { From d6d4fcaaf2d21074ff5229ac1203ca838c42484c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Sep 2025 10:35:08 +0000 Subject: [PATCH 3/4] Add documentation for 7 more test suites (node, keys-mashup, null-keys, simple-override, unavailable-override, include-skip) Co-authored-by: kamilkisiela <8167190+kamilkisiela@users.noreply.github.com> --- src/test-suites/include-skip/README.md | 72 +++++++++++++++++++ src/test-suites/include-skip/test.ts | 20 ++++++ src/test-suites/keys-mashup/README.md | 56 +++++++++++++++ src/test-suites/keys-mashup/test.ts | 6 ++ src/test-suites/node/README.md | 46 ++++++++++++ src/test-suites/node/test.ts | 6 ++ src/test-suites/null-keys/README.md | 56 +++++++++++++++ src/test-suites/null-keys/test.ts | 6 ++ src/test-suites/simple-override/README.md | 61 ++++++++++++++++ src/test-suites/simple-override/test.ts | 10 +++ .../unavailable-override/README.md | 68 ++++++++++++++++++ src/test-suites/unavailable-override/test.ts | 9 +++ 12 files changed, 416 insertions(+) create mode 100644 src/test-suites/include-skip/README.md create mode 100644 src/test-suites/keys-mashup/README.md create mode 100644 src/test-suites/node/README.md create mode 100644 src/test-suites/null-keys/README.md create mode 100644 src/test-suites/simple-override/README.md create mode 100644 src/test-suites/unavailable-override/README.md diff --git a/src/test-suites/include-skip/README.md b/src/test-suites/include-skip/README.md new file mode 100644 index 00000000..17f6d4bd --- /dev/null +++ b/src/test-suites/include-skip/README.md @@ -0,0 +1,72 @@ +# Include Skip + +## Overview +This test suite validates that the standard GraphQL `@include` and `@skip` directives work correctly in Apollo Federation, ensuring that conditional field inclusion and exclusion behave as expected in federated queries. + +## Apollo Federation Concepts Tested +- **@include directive**: Conditionally including fields based on variable values +- **@skip directive**: Conditionally excluding fields based on variable values +- **Query variable handling**: How federated gateways process GraphQL variables +- **Conditional field resolution**: Ensuring resolvers are only called for included fields +- **Query optimization**: Skipping unnecessary field resolution in federated environments + +## Test Scenario +The test involves a Product entity with various fields that can be conditionally included or excluded: + +1. **Standard Fields**: Always present fields like `price` +2. **Conditional Fields**: Fields controlled by `@include` and `@skip` directives +3. **Variable Control**: Using GraphQL variables to control directive behavior + +## Test Cases + +### 1. @include Directive with False Condition +- Tests that fields with `@include(if: false)` are completely omitted from the response +- Verifies that the gateway doesn't call resolvers for excluded fields +- Ensures query optimization by avoiding unnecessary field resolution + +### 2. @skip Directive with True Condition +- Tests that fields with `@skip(if: true)` are completely omitted from the response +- Verifies that skipped fields don't appear in the final result +- Validates that the gateway respects skip conditions during query execution + +### 3. @include Directive with True Condition +- Tests that fields with `@include(if: true)` are included in the response +- Verifies that included fields are properly resolved and return their values +- Ensures that conditional inclusion works correctly when the condition is met + +### 4. @skip Directive with False Condition +- Tests that fields with `@skip(if: false)` are included in the response +- Verifies that non-skipped fields are properly resolved and return their values +- Validates that skip directives only exclude fields when the condition is true + +## What's Being Tested + +### Directive Processing +1. **Condition Evaluation**: The gateway correctly evaluates boolean conditions for directives +2. **Field Filtering**: Fields are properly included or excluded based on directive conditions +3. **Variable Resolution**: GraphQL variables are correctly passed to and evaluated by directives + +### Federation Integration +1. **Cross-Subgraph Directives**: `@include` and `@skip` work correctly across federated subgraphs +2. **Query Planning**: The gateway optimizes query plans by excluding skipped fields +3. **Resolver Optimization**: Resolvers are not called for fields that will be excluded + +### Standard Compliance +1. **GraphQL Specification**: `@include` and `@skip` behave according to GraphQL standards +2. **Variable Handling**: Default values and variable passing work correctly +3. **Response Format**: Conditional fields are properly omitted from responses + +## Why This Matters +Conditional field directives are important for: +- **Performance Optimization**: Avoiding unnecessary data fetching and computation +- **Dynamic UIs**: Frontend applications that conditionally render based on user state +- **API Efficiency**: Reducing payload size by excluding unneeded data +- **Bandwidth Optimization**: Especially important for mobile applications + +## Implementation Notes +These directives should be processed during query planning, not during execution: +- **Query Planning**: The gateway should exclude skipped fields from subgraph queries +- **Network Optimization**: Subgraphs shouldn't be asked to resolve excluded fields +- **Response Shaping**: Final response should naturally omit conditional fields + +This test ensures that federated gateways maintain the same conditional field behavior as monolithic GraphQL servers, preserving client expectations and optimization opportunities. \ No newline at end of file diff --git a/src/test-suites/include-skip/test.ts b/src/test-suites/include-skip/test.ts index 45b31650..010365fa 100644 --- a/src/test-suites/include-skip/test.ts +++ b/src/test-suites/include-skip/test.ts @@ -1,6 +1,11 @@ import { createTest } from "../../testkit.js"; export default [ + // Test @include directive with false condition + // Verifies that fields with @include(if: false) are not included in the response + // - neverCalledInclude field should not appear because $bool defaults to false + // - Tests that the gateway correctly processes @include directives + // - Ensures conditional field inclusion works in federated queries createTest( /* GraphQL */ ` query ($bool: Boolean = false) { @@ -18,6 +23,11 @@ export default [ }, }, ), + // Test @skip directive with true condition + // Verifies that fields with @skip(if: true) are not included in the response + // - neverCalledSkip field should not appear because $bool defaults to true + // - Tests that the gateway correctly processes @skip directives + // - Ensures conditional field exclusion works in federated queries createTest( /* GraphQL */ ` query ($bool: Boolean = true) { @@ -35,6 +45,11 @@ export default [ }, }, ), + // Test @include directive with true condition + // Verifies that fields with @include(if: true) are included in the response + // - include field should appear and return its value because $bool is true + // - Tests that @include directive correctly includes fields when condition is met + // - Validates that federated resolvers are called for included fields createTest( /* GraphQL */ ` query ($bool: Boolean = true) { @@ -53,6 +68,11 @@ export default [ }, }, ), + // Test @skip directive with false condition + // Verifies that fields with @skip(if: false) are included in the response + // - skip field should appear and return its value because $bool is false + // - Tests that @skip directive correctly includes fields when condition is not met + // - Validates that federated resolvers are called for non-skipped fields createTest( /* GraphQL */ ` query ($bool: Boolean = false) { diff --git a/src/test-suites/keys-mashup/README.md b/src/test-suites/keys-mashup/README.md new file mode 100644 index 00000000..1802e233 --- /dev/null +++ b/src/test-suites/keys-mashup/README.md @@ -0,0 +1,56 @@ +# Keys Mashup + +## Overview +This test suite validates complex entity key relationships in Apollo Federation, testing scenarios where entities have multiple interconnected key fields and can be resolved through different paths across subgraphs. + +## Apollo Federation Concepts Tested +- **Complex entity keys**: Entities with multiple potential key strategies +- **Cross-subgraph entity resolution**: Resolving entities that span multiple subgraphs +- **Entity relationship chains**: Entities that reference other entities through various key patterns +- **Multi-hop resolution**: Following entity relationships across multiple subgraphs + +## Test Scenario +The test involves two entity types with complex interdependencies: + +1. **Entity A**: Can be resolved using different key strategies +2. **Entity B**: References multiple Entity A instances through various key patterns + +The subgraphs demonstrate: +- Different ways to identify and resolve the same entity type +- How entities can have fields contributed by multiple subgraphs +- Complex key matching strategies that work across subgraph boundaries + +## Test Case + +### Complex Entity Key Resolution +- Tests that Entity B can resolve its relationship to multiple Entity A instances +- Verifies that each Entity A instance gets fields from appropriate subgraphs: + - `id` and `name` from one subgraph + - `nameInB` field from another subgraph that extends Entity A +- Demonstrates that the gateway can handle complex entity resolution patterns + +## What's Being Tested + +### Advanced Key Strategies +1. **Multiple Key Definitions**: Entities can be defined with different key fields in different subgraphs +2. **Key Resolution Logic**: The gateway correctly chooses the appropriate key strategy for resolution +3. **Cross-Reference Handling**: Entities can reference each other through various key patterns + +### Federation Complexity +1. **Multi-Subgraph Entities**: Single entities can have fields distributed across multiple subgraphs +2. **Relationship Resolution**: Complex object relationships work correctly across subgraph boundaries +3. **Performance Optimization**: The gateway efficiently resolves complex entity graphs + +### Data Consistency +1. **Key Matching**: Different key strategies for the same entity produce consistent results +2. **Field Distribution**: Fields from different subgraphs are correctly merged for each entity +3. **Relationship Integrity**: Entity relationships maintain data integrity across resolution hops + +## Why This Matters +Complex entity key patterns are important for: +- **Legacy System Integration**: Different systems may identify the same entities using different keys +- **Performance Optimization**: Multiple key strategies allow for optimized query paths +- **Flexible Architecture**: Teams can evolve their entity identification strategies independently +- **Real-World Complexity**: Production systems often have complex, interconnected entity relationships + +This test ensures that federated gateways can handle sophisticated entity resolution scenarios that are common in large, distributed systems where multiple teams manage interconnected data. \ No newline at end of file diff --git a/src/test-suites/keys-mashup/test.ts b/src/test-suites/keys-mashup/test.ts index 25483154..46c733ff 100644 --- a/src/test-suites/keys-mashup/test.ts +++ b/src/test-suites/keys-mashup/test.ts @@ -1,6 +1,12 @@ import { createTest } from "../../testkit.js"; export default [ + // Test complex entity key relationships between multiple subgraphs + // Verifies that entities can be resolved using different key fields across subgraphs + // - Entity B references multiple Entity A instances + // - Each subgraph can resolve Entity A using different key strategies + // - Tests that field resolution works correctly across the entity relationship chain + // This demonstrates advanced federation patterns where entities have complex interdependencies createTest( /* GraphQL */ ` query { diff --git a/src/test-suites/node/README.md b/src/test-suites/node/README.md new file mode 100644 index 00000000..cd1b0131 --- /dev/null +++ b/src/test-suites/node/README.md @@ -0,0 +1,46 @@ +# Node + +## Overview +This test suite validates the Node interface pattern in Apollo Federation, which is a common GraphQL pattern for global object identification, often used in Relay-style architectures. + +## Apollo Federation Concepts Tested +- **Interface resolution**: How federated schemas handle interface types +- **Inline fragments**: Using type-specific field selection with `... on Type` +- **__typename field**: Introspection field for type identification +- **Global object identification**: The Node pattern for uniquely identifying objects across the graph + +## Test Scenario +The test implements the Node interface pattern where: + +1. **Node Interface**: A global interface that can be implemented by any type that has a unique `id` +2. **Product Implementation**: The Product type implements the Node interface +3. **Global Access**: Objects can be accessed globally through the Node interface + +## Test Case + +### Node Interface Resolution with Inline Fragments +- Tests that a query for a Node interface correctly resolves to the concrete Product type +- Verifies that inline fragments (`... on Product`) work correctly with federated interfaces +- Validates that all requested fields (id, name, __typename, price) are properly resolved +- Ensures the __typename field correctly identifies the concrete type + +## What's Being Tested + +### Interface Federation +1. **Interface Distribution**: Interfaces can be properly federated across subgraphs +2. **Type Resolution**: The gateway correctly resolves interface queries to concrete types +3. **Fragment Execution**: Inline fragments execute correctly on federated types + +### Node Pattern Support +1. **Global Identification**: Objects can be accessed through a global Node interface +2. **Type Safety**: The interface pattern maintains type safety in federated environments +3. **Relay Compatibility**: The pattern supports Relay-style client requirements + +## Why This Matters +The Node interface pattern is crucial for: +- **Global Object Identification**: Clients can access any object by its global ID +- **Caching**: Client-side caches can efficiently normalize data using global IDs +- **Refetching**: Objects can be refetched individually using their global identifiers +- **Relay Integration**: Essential for applications using Relay or similar frameworks + +This test ensures that federated schemas maintain compatibility with the Node pattern, enabling advanced client-side features and maintaining consistency with GraphQL best practices. \ No newline at end of file diff --git a/src/test-suites/node/test.ts b/src/test-suites/node/test.ts index 0da07cec..02c2097e 100644 --- a/src/test-suites/node/test.ts +++ b/src/test-suites/node/test.ts @@ -1,6 +1,12 @@ import { createTest } from "../../testkit.js"; export default [ + // Test Node interface pattern with inline fragments + // Verifies that the Node interface (common pattern in GraphQL) works in federation + // - productNode query returns a Node interface that resolves to Product type + // - Tests inline fragment selection on concrete type + // - Validates __typename field resolution within fragments + // This pattern is commonly used for Relay-style pagination and global object identification createTest( /* GraphQL */ ` { diff --git a/src/test-suites/null-keys/README.md b/src/test-suites/null-keys/README.md new file mode 100644 index 00000000..db8593d4 --- /dev/null +++ b/src/test-suites/null-keys/README.md @@ -0,0 +1,56 @@ +# Null Keys + +## Overview +This test suite validates that Apollo Federation correctly handles null values in entity key fields and relationships, ensuring that the federated query execution doesn't break when encountering optional relationships or missing data. + +## Apollo Federation Concepts Tested +- **Null value handling**: How the gateway processes null values in entity relationships +- **Optional relationships**: Entity references that may or may not exist +- **Graceful degradation**: Continuing query execution when some data is missing +- **Entity resolution robustness**: Maintaining query execution integrity with partial data + +## Test Scenario +The test involves a book catalog system where: + +1. **BookContainer**: Contains book information +2. **Book**: Has a UPC identifier and an optional author relationship +3. **Author**: May or may not exist for each book (some books have null authors) + +The scenario tests that the gateway properly handles: +- Books with valid author relationships +- Books with null author relationships +- Mixed data sets containing both scenarios + +## Test Case + +### Null Author Relationship Handling +- Tests a query that requests book containers with book and author information +- Verifies that books with valid authors return complete data +- Ensures that books with null authors gracefully return null for the author field +- Validates that the presence of null values doesn't break the overall query execution + +## What's Being Tested + +### Null Value Propagation +1. **Null Safety**: The gateway correctly propagates null values through entity resolution +2. **Partial Results**: Queries can return partial results when some relationships are null +3. **Data Integrity**: Null values don't corrupt or prevent other valid data from being returned + +### Query Execution Robustness +1. **Error Handling**: Null values in entity keys don't cause query failures +2. **Mixed Data Sets**: Queries correctly handle arrays containing both valid and null references +3. **Field Resolution**: Non-null fields continue to resolve correctly even when related fields are null + +### Real-World Scenarios +1. **Optional Relationships**: Common pattern where entities may or may not have certain relationships +2. **Data Migration**: Scenarios where some entities haven't been fully populated yet +3. **Legacy Data**: Systems with incomplete or missing relationship data + +## Why This Matters +Null value handling is crucial for: +- **Data Quality**: Real-world data often has missing or incomplete relationships +- **Gradual Migration**: Systems being migrated to federation may have partial data +- **Optional Features**: Not all entities require all relationships to be meaningful +- **User Experience**: Applications should gracefully handle missing data without breaking + +This test ensures that federated gateways maintain robust query execution even when encountering incomplete or missing data, which is essential for production systems where data quality may vary and relationships are often optional. \ No newline at end of file diff --git a/src/test-suites/null-keys/test.ts b/src/test-suites/null-keys/test.ts index db2a9b19..fa64b00d 100644 --- a/src/test-suites/null-keys/test.ts +++ b/src/test-suites/null-keys/test.ts @@ -1,6 +1,12 @@ import { createTest } from "../../testkit.js"; export default [ + // Test handling of null values in entity key fields + // Verifies that the gateway correctly handles entities with null relationships + // - bookContainers query returns a list with some null author relationships + // - Tests that entity resolution gracefully handles null foreign keys + // - Ensures that null values don't break the federated query execution + // This is important for real-world scenarios where relationships may be optional createTest( /* GraphQL */ ` query { diff --git a/src/test-suites/simple-override/README.md b/src/test-suites/simple-override/README.md new file mode 100644 index 00000000..b6f5dd80 --- /dev/null +++ b/src/test-suites/simple-override/README.md @@ -0,0 +1,61 @@ +# Simple Override + +## Overview +This test suite validates the basic functionality of the `@override` directive in Apollo Federation, which allows one subgraph to take ownership of a field that was previously defined in another subgraph. + +## Apollo Federation Concepts Tested +- **@override directive**: Transferring field ownership between subgraphs +- **@shareable directive**: Fields that can be resolved by multiple subgraphs +- **Field resolution precedence**: How the gateway determines which subgraph resolves a field +- **Schema evolution**: Migrating field ownership between subgraphs + +## Test Scenario +The test involves two subgraphs managing Post entities: + +1. **Subgraph A**: + - Originally owns the `createdAt` field on `Post` type + - Marks `createdAt` as `@shareable` + - Provides `feed` and `aFeed` queries + +2. **Subgraph B**: + - Uses `@override(from: "a")` to take ownership of `createdAt` field + - Also marks `createdAt` as `@shareable` + - Provides `feed` and `bFeed` queries + +## Test Cases + +### 1. Basic Override Functionality +- Tests that queries for `feed` get the `createdAt` field resolved by subgraph B +- Verifies that the `@override` directive successfully transfers field ownership +- Ensures that the gateway routes field resolution to the overriding subgraph + +### 2. Override Consistency Across Query Sources +- Tests that the override behavior is consistent regardless of which query is used +- Verifies that both subgraph-specific queries (`aFeed`, `bFeed`) respect the override +- Ensures that field ownership changes apply globally, not just to specific queries + +## What's Being Tested + +### Field Ownership Migration +1. **Ownership Transfer**: The `@override` directive successfully transfers field responsibility +2. **Resolution Routing**: The gateway correctly routes field resolution to the overriding subgraph +3. **Consistency**: Field resolution behavior is consistent across all query entry points + +### Schema Evolution Support +1. **Gradual Migration**: Teams can gradually migrate field ownership between subgraphs +2. **Backwards Compatibility**: Existing queries continue to work during field migration +3. **Deployment Safety**: Override changes can be deployed safely without breaking clients + +### Gateway Behavior +1. **Directive Processing**: The gateway correctly interprets and applies `@override` directives +2. **Query Planning**: Override directives are properly considered during query planning +3. **Field Resolution**: The correct subgraph is chosen for field resolution + +## Why This Matters +The `@override` directive is crucial for: +- **Schema Evolution**: Teams can migrate field ownership as their architecture evolves +- **Performance Optimization**: Moving field resolution closer to the data source +- **Team Boundaries**: Allowing teams to take ownership of fields relevant to their domain +- **Technical Debt**: Enabling gradual refactoring of federated schemas + +This test ensures that the fundamental `@override` functionality works correctly, enabling teams to evolve their federated schemas safely and efficiently. \ No newline at end of file diff --git a/src/test-suites/simple-override/test.ts b/src/test-suites/simple-override/test.ts index 030ec0ec..e90985d6 100644 --- a/src/test-suites/simple-override/test.ts +++ b/src/test-suites/simple-override/test.ts @@ -1,6 +1,11 @@ import { createTest } from "../../testkit.js"; export default [ + // Test basic @override directive functionality + // Verifies that subgraph B can override the createdAt field from subgraph A + // - Both subgraphs define the same feed query and Post type + // - Subgraph B uses @override(from: "a") to take ownership of createdAt field + // - Tests that the gateway routes field resolution to the overriding subgraph createTest( /* GraphQL */ ` query { @@ -22,6 +27,11 @@ export default [ }, }, ), + // Test that @override works with different query entry points + // Verifies that field override behavior is consistent across different queries + // - aFeed and bFeed are subgraph-specific queries returning different posts + // - Both should use the overridden createdAt field resolution from subgraph B + // - Tests that @override directive affects field resolution regardless of query source createTest( /* GraphQL */ ` query { diff --git a/src/test-suites/unavailable-override/README.md b/src/test-suites/unavailable-override/README.md new file mode 100644 index 00000000..bc2a1cb6 --- /dev/null +++ b/src/test-suites/unavailable-override/README.md @@ -0,0 +1,68 @@ +# Unavailable Override + +## Overview +This test suite validates how Apollo Federation handles the `@override` directive when it references a non-existent subgraph, testing the gateway's resilience and error handling capabilities. + +## Apollo Federation Concepts Tested +- **@override directive error handling**: Behavior when override source doesn't exist +- **Schema validation**: How gateways handle invalid directive references +- **Fallback behavior**: What happens when override cannot be applied +- **Gateway resilience**: Continuing operation despite schema configuration errors + +## Test Scenario +The test involves a scenario where subgraph configuration contains an error: + +1. **Subgraph A**: + - Defines the `Post` type with `createdAt` field + - Marks `createdAt` as `@shareable` + - Provides query functionality + +2. **Subgraph B**: + - Attempts to override `createdAt` with `@override(from: "non-existing")` + - References a subgraph that doesn't exist in the federation + - Tests how the gateway handles this invalid configuration + +## Test Cases + +### 1. Invalid Override Reference Handling +- Tests that queries still work when `@override` references a non-existent subgraph +- Verifies that the gateway doesn't crash or fail due to invalid override configuration +- Ensures that field resolution falls back to available implementations + +### 2. Consistent Behavior Across Queries +- Tests that the invalid override doesn't affect different query entry points +- Verifies that both subgraph-specific queries continue to work normally +- Ensures that the error handling is consistent across the entire schema + +## What's Being Tested + +### Error Resilience +1. **Invalid References**: How the gateway handles `@override` references to non-existent subgraphs +2. **Graceful Degradation**: Continuing normal operation despite configuration errors +3. **Fallback Logic**: Using available field implementations when override fails + +### Schema Validation +1. **Configuration Validation**: Whether invalid `@override` directives are detected +2. **Runtime Behavior**: How the gateway behaves with invalid directive configurations +3. **Error Recovery**: Whether the system can recover from schema configuration errors + +### Operational Stability +1. **Service Continuity**: Ensuring services remain operational despite configuration errors +2. **Query Execution**: Normal query processing continues with invalid overrides present +3. **System Robustness**: The federation remains stable with problematic schema configurations + +## Why This Matters +Testing invalid override scenarios is important for: +- **Production Resilience**: Real deployments may have configuration errors +- **Deployment Safety**: Understanding what happens when deployments contain mistakes +- **Error Recovery**: Ensuring systems can continue operating during configuration issues +- **Developer Experience**: Providing clear behavior when schema configuration is incorrect + +## Expected Behaviors +Different gateways might handle this scenario differently: +- **Strict Validation**: Reject the schema entirely during composition +- **Warning Mode**: Accept the schema but log warnings about invalid references +- **Ignore Mode**: Ignore the invalid override and use available field implementations +- **Error Mode**: Fail queries that encounter invalid override directives + +This test helps identify how different gateway implementations handle edge cases and configuration errors, which is crucial for understanding their production behavior and reliability characteristics. \ No newline at end of file diff --git a/src/test-suites/unavailable-override/test.ts b/src/test-suites/unavailable-override/test.ts index 030ec0ec..89f8f4d2 100644 --- a/src/test-suites/unavailable-override/test.ts +++ b/src/test-suites/unavailable-override/test.ts @@ -1,6 +1,11 @@ import { createTest } from "../../testkit.js"; export default [ + // Test @override directive with non-existing source subgraph + // Verifies that @override gracefully handles references to non-existent subgraphs + // - Subgraph B tries to override from "non-existing" subgraph + // - Tests that the gateway handles invalid @override references without breaking + // - Should fall back to normal field resolution when override source doesn't exist createTest( /* GraphQL */ ` query { @@ -22,6 +27,10 @@ export default [ }, }, ), + // Test that invalid @override doesn't affect multiple query sources + // Verifies consistent behavior across different query entry points + // - Both aFeed and bFeed should work normally despite invalid override + // - Tests resilience of the gateway when schema contains invalid @override references createTest( /* GraphQL */ ` query { From d1c24880178c2987f065fdb6af2df92974a0d2ed Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Sep 2025 10:40:17 +0000 Subject: [PATCH 4/4] Add documentation for 5 more test suites (simple-inaccessible, fed1-external-extends-resolvable, parent-entity-call-complex, fed2-external-extends, complex-entity-call) Co-authored-by: kamilkisiela <8167190+kamilkisiela@users.noreply.github.com> --- src/test-suites/complex-entity-call/README.md | 89 +++++++++++++++++++ src/test-suites/complex-entity-call/test.ts | 8 ++ .../README.md | 65 ++++++++++++++ .../fed1-external-extends-resolvable/test.ts | 6 ++ .../fed2-external-extends/README.md | 82 +++++++++++++++++ src/test-suites/fed2-external-extends/test.ts | 18 ++++ .../parent-entity-call-complex/README.md | 80 +++++++++++++++++ .../parent-entity-call-complex/test.ts | 7 ++ src/test-suites/simple-inaccessible/README.md | 77 ++++++++++++++++ src/test-suites/simple-inaccessible/test.ts | 16 ++++ 10 files changed, 448 insertions(+) create mode 100644 src/test-suites/complex-entity-call/README.md create mode 100644 src/test-suites/fed1-external-extends-resolvable/README.md create mode 100644 src/test-suites/fed2-external-extends/README.md create mode 100644 src/test-suites/parent-entity-call-complex/README.md create mode 100644 src/test-suites/simple-inaccessible/README.md diff --git a/src/test-suites/complex-entity-call/README.md b/src/test-suites/complex-entity-call/README.md new file mode 100644 index 00000000..e61cf672 --- /dev/null +++ b/src/test-suites/complex-entity-call/README.md @@ -0,0 +1,89 @@ +# Complex Entity Call + +## Overview +This test suite validates the most sophisticated entity resolution scenarios in Apollo Federation, testing complex multi-entity graphs with circular references, nested relationships, and intricate data dependencies that represent real-world federated architectures. + +## Apollo Federation Concepts Tested +- **Complex entity graphs**: Multiple entities with interconnected relationships +- **Circular references**: Entities that reference back to themselves or each other +- **Nested entity resolution**: Multi-level entity resolution chains +- **Object wrapper patterns**: Using object types to wrap scalar values +- **Multi-subgraph coordination**: Coordinating data across multiple federated subgraphs +- **Query planning optimization**: Efficient resolution of complex entity graphs + +## Test Scenario +The test involves a sophisticated e-commerce data model: + +1. **Product Entity**: + - Has `id`, `pid` fields + - Contains a `price` object (not scalar) + - References a `category` entity + +2. **Category Entity**: + - Has `id`, `tag` fields + - Contains a `mainProduct` reference back to Product (circular) + +3. **Price Object**: + - Wraps the actual price value in an object structure + - Demonstrates object-type field resolution + +4. **TopProducts Query Result**: + - Returns products array with complex nested data + - Includes `selected` and `first` product references + - Demonstrates multiple access patterns to the same entity types + +## Test Case + +### Complex Multi-Entity Resolution with Circular References +The single test validates an extremely complex query that: +- Fetches an array of products with nested category and price data +- Resolves circular references (Product → Category → mainProduct → Product) +- Handles object-wrapped scalar values (price.price) +- Resolves additional product references (selected, first) +- Coordinates data from multiple subgraphs seamlessly + +## What's Being Tested + +### Advanced Entity Patterns +1. **Circular Reference Handling**: Properly resolving entities that reference each other +2. **Object Type Resolution**: Resolving complex object types, not just scalars +3. **Multi-Path Access**: Accessing the same entity types through different query paths + +### Performance and Optimization +1. **Query Planning**: Efficient planning for complex, nested entity graphs +2. **Deduplication**: Avoiding duplicate entity resolutions when the same entities are accessed multiple times +3. **Batching**: Efficiently batching entity resolution requests + +### Real-World Complexity +1. **Production Patterns**: Testing patterns commonly found in production systems +2. **Data Relationships**: Complex business relationships between entities +3. **Scalability**: Ensuring federation scales to complex data models + +## Why This Matters +Complex entity resolution is critical for: +- **Real-World Applications**: Production systems often have sophisticated entity relationships +- **Performance**: Complex queries need to be resolved efficiently +- **Data Integrity**: Ensuring circular references don't cause infinite loops +- **Developer Experience**: Complex patterns should work intuitively + +## Common Real-World Scenarios +This pattern represents scenarios like: +- **E-commerce**: Products with categories that have featured products +- **Social Networks**: Users with friends who have mutual connections +- **Content Management**: Articles with authors who have featured articles +- **Organizational Charts**: Employees with managers who have direct reports + +## Implementation Challenges +Gateways must handle: +- **Cycle Detection**: Preventing infinite loops in circular references +- **Query Optimization**: Minimizing round trips for complex entity graphs +- **Memory Management**: Efficiently handling large, interconnected entity graphs +- **Error Propagation**: Gracefully handling failures in complex resolution chains + +## Performance Considerations +- **Entity Deduplication**: Same entities accessed multiple times should be resolved once +- **Batching Strategies**: Related entities should be resolved in batches when possible +- **Query Planning**: Complex queries need sophisticated planning for optimal execution +- **Caching**: Entity resolution results should be cached to avoid redundant work + +This test ensures that federated gateways can handle the most complex entity resolution scenarios that production applications require, validating both correctness and performance of sophisticated federation patterns. \ No newline at end of file diff --git a/src/test-suites/complex-entity-call/test.ts b/src/test-suites/complex-entity-call/test.ts index c10b6fd9..0282c3d4 100644 --- a/src/test-suites/complex-entity-call/test.ts +++ b/src/test-suites/complex-entity-call/test.ts @@ -1,6 +1,14 @@ import { createTest } from "../../testkit.js"; export default [ + // Test complex multi-entity resolution with nested relationships + // Verifies that complex entity graphs can be resolved across multiple subgraphs + // - topProducts query involves multiple entity types: Product, Category, Price + // - Tests circular relationships: Category -> mainProduct -> Category + // - Validates that nested entity resolution works correctly + // - price field uses object wrapper pattern + // - category.mainProduct creates a circular reference back to Product + // This represents real-world complex data relationships in federated systems createTest( /* GraphQL */ ` query { diff --git a/src/test-suites/fed1-external-extends-resolvable/README.md b/src/test-suites/fed1-external-extends-resolvable/README.md new file mode 100644 index 00000000..0e50a654 --- /dev/null +++ b/src/test-suites/fed1-external-extends-resolvable/README.md @@ -0,0 +1,65 @@ +# Fed1 External Extends Resolvable + +## Overview +This test suite validates compatibility with Apollo Federation v1 syntax, specifically testing the combination of `@external` and `@extends` directives that were used in Federation v1 to extend types across subgraphs. + +## Apollo Federation Concepts Tested +- **Federation v1 compatibility**: Support for legacy Federation v1 directive syntax +- **@extends directive**: Federation v1 method for extending types defined in other subgraphs +- **@external directive**: Marking fields as owned by other subgraphs (same in v1 and v2) +- **Entity resolution**: How v1-style type extensions work with entity resolution +- **Migration support**: Ensuring v1 schemas can work with modern gateways + +## Test Scenario +The test involves a Product entity that is distributed across subgraphs using Federation v1 patterns: + +1. **Base Product Definition**: One subgraph defines the core Product type +2. **Product Extension**: Another subgraph extends the Product type using `@extends` +3. **Field Dependencies**: Extended fields depend on `@external` fields from the base definition + +## Test Case + +### Federation v1 Type Extension Resolution +- Tests that a Product entity can be successfully resolved across multiple subgraphs +- Verifies that `@extends` directive correctly extends types from other subgraphs +- Validates that `@external` fields are properly used for entity resolution +- Ensures all fields (id, pid, price, upc, name) are correctly resolved from their respective subgraphs + +## What's Being Tested + +### Legacy Syntax Support +1. **@extends Directive**: The Federation v1 syntax for type extension still works +2. **@external Fields**: v1-style external field declarations are properly handled +3. **Entity Resolution**: v1 extension patterns work with modern entity resolution + +### Migration Compatibility +1. **Schema Evolution**: v1 schemas can be gradually migrated to v2 without breaking +2. **Gateway Support**: Modern gateways support legacy Federation v1 syntax +3. **Interoperability**: v1 and v2 syntax can potentially coexist in the same federation + +### Functional Equivalence +1. **Feature Parity**: v1 extension patterns provide the same functionality as v2 +2. **Resolution Consistency**: Entity resolution works the same way regardless of syntax version +3. **Performance**: No performance degradation when using v1 syntax + +## Why This Matters +Federation v1 compatibility is important for: +- **Migration Paths**: Organizations can upgrade gateways without rewriting schemas +- **Legacy Support**: Existing Federation v1 deployments continue to work +- **Gradual Adoption**: Teams can migrate to v2 syntax incrementally +- **Investment Protection**: Existing Federation v1 investments remain valuable + +## Federation v1 vs v2 Differences +- **v1**: Uses `@extends` to extend types defined in other subgraphs +- **v2**: Uses `@key` directives and type redefinition to achieve the same result +- **v1**: Requires explicit `@extends` for any type extension +- **v2**: More flexible syntax with better composition capabilities + +## Migration Considerations +When migrating from v1 to v2: +1. Replace `@extends` with `@key` directives on redefined types +2. Update import statements to use v2 directive URLs +3. Consider using v2-specific features like `@shareable` and `@override` +4. Test thoroughly to ensure functional equivalence + +This test ensures that organizations using Federation v1 can confidently upgrade their gateway infrastructure while maintaining their existing schema patterns. \ No newline at end of file diff --git a/src/test-suites/fed1-external-extends-resolvable/test.ts b/src/test-suites/fed1-external-extends-resolvable/test.ts index 737e8031..ecb03a2e 100644 --- a/src/test-suites/fed1-external-extends-resolvable/test.ts +++ b/src/test-suites/fed1-external-extends-resolvable/test.ts @@ -1,6 +1,12 @@ import { createTest } from "../../testkit.js"; export default [ + // Test Federation v1 @external and @extends directives working together + // Verifies that a type can be extended using @extends and resolve fields + // that depend on @external fields from the original definition + // - productInA query returns a Product that spans multiple subgraphs + // - Tests that Federation v1 patterns still work correctly + // - Validates that @external fields can be used for entity resolution createTest( /* GraphQL */ ` query { diff --git a/src/test-suites/fed2-external-extends/README.md b/src/test-suites/fed2-external-extends/README.md new file mode 100644 index 00000000..4be2a146 --- /dev/null +++ b/src/test-suites/fed2-external-extends/README.md @@ -0,0 +1,82 @@ +# Fed2 External Extends + +## Overview +This test suite validates Apollo Federation v2 syntax and patterns, specifically testing the modern approach to type extension and external field handling that replaced Federation v1's `@extends` directive. + +## Apollo Federation Concepts Tested +- **Federation v2 syntax**: Modern approach to type extension using `@key` directives +- **@external directive**: v2 usage of external fields (same concept as v1 but improved syntax) +- **@provides directive**: v2 optimization for providing external fields +- **Entity redefinition**: v2 pattern of redefining types instead of extending them +- **Type composition**: How v2 composes types across subgraphs + +## Test Scenario +The test demonstrates Federation v2 patterns for user entity management: + +1. **User Entity Distribution**: User type is defined across multiple subgraphs using v2 patterns +2. **External Field Handling**: Fields like `rid` are marked as external and properly resolved +3. **Provides Optimization**: One subgraph uses `@provides` to optimize field resolution +4. **Modern Syntax**: Uses v2 directive imports and patterns throughout + +## Test Cases + +### 1. Multi-Query Entity Resolution +- Tests multiple user queries in a single request +- Verifies that different entry points (randomUser, userById) work correctly +- Validates that entity resolution works with v2 `@key` patterns + +### 2. External Field Resolution +- Tests that `@external` fields can be properly resolved in v2 +- Verifies that `rid` field (marked as external) is correctly fetched +- Ensures v2 external field patterns work efficiently + +### 3. Combined Field Resolution +- Tests resolving both local and external fields together +- Verifies that v2 entity composition works for complex field sets +- Ensures optimal query planning for mixed field types + +### 4. Provides Directive Optimization +- Tests the `@provides` directive functionality in v2 +- Verifies that provided fields reduce necessary subgraph calls +- Validates that v2 provides patterns work correctly + +## What's Being Tested + +### Federation v2 Features +1. **Modern Syntax**: v2 directive syntax and import patterns +2. **Type Redefinition**: v2 approach to extending types without `@extends` +3. **Improved Composition**: Better type composition capabilities in v2 + +### Performance Optimizations +1. **@provides Usage**: Reducing round trips through field provision +2. **Query Planning**: Efficient query planning with v2 patterns +3. **Entity Resolution**: Optimized entity resolution strategies + +### Syntax Evolution +1. **v1 to v2 Migration**: How v2 improves upon v1 patterns +2. **Directive Improvements**: Enhanced directive capabilities in v2 +3. **Schema Composition**: Better schema merging in v2 + +## Why This Matters +Federation v2 is important because it: +- **Improved Developer Experience**: Cleaner, more intuitive syntax +- **Better Performance**: More optimization opportunities +- **Enhanced Features**: New directives like `@shareable`, `@override`, `@inaccessible` +- **Future-Proofing**: Foundation for future federation enhancements + +## Federation v2 Advantages +Compared to v1, Federation v2 offers: +- **No @extends Required**: Types can be redefined directly with `@key` +- **Better Composition**: More flexible type composition patterns +- **New Directives**: Additional directives for advanced use cases +- **Improved Validation**: Better schema validation and error reporting +- **Performance**: Better query planning and execution + +## Migration Considerations +When migrating from v1 to v2: +1. **Update Imports**: Change to v2 directive URLs +2. **Replace @extends**: Use `@key` on redefined types instead +3. **New Features**: Consider using new v2-specific directives +4. **Testing**: Ensure functional equivalence after migration + +This test validates that modern federation gateways properly support Federation v2 syntax and can efficiently execute v2-style federated schemas. \ No newline at end of file diff --git a/src/test-suites/fed2-external-extends/test.ts b/src/test-suites/fed2-external-extends/test.ts index f949759a..a3461ae7 100644 --- a/src/test-suites/fed2-external-extends/test.ts +++ b/src/test-suites/fed2-external-extends/test.ts @@ -1,6 +1,11 @@ import { createTest } from "../../testkit.js"; export default [ + // Test Federation v2 type extension and entity resolution patterns + // Verifies that Federation v2 syntax works correctly for extending types + // - Multiple queries test different aspects of v2 entity resolution + // - userById query tests entity resolution with multiple fields + // - Tests that v2 @key directive and type redefinition work properly createTest( /* GraphQL */ ` query { @@ -29,6 +34,10 @@ export default [ }, }, ), + // Test entity resolution with Federation v2 external field patterns + // Verifies that external fields in v2 can be properly resolved + // - rid field demonstrates v2 external field handling + // - Tests that @external directive works with v2 syntax createTest( /* GraphQL */ ` query { @@ -47,6 +56,10 @@ export default [ }, }, ), + // Test complex field resolution combining v2 patterns + // Verifies that multiple fields can be resolved together in v2 + // - Combines both local and external fields in single query + // - Tests efficiency of v2 entity resolution patterns createTest( /* GraphQL */ ` query { @@ -67,6 +80,11 @@ export default [ }, }, ), + // Test Federation v2 provides directive functionality + // Verifies that @provides works correctly with v2 syntax + // - providedRandomUser query uses @provides optimization + // - Tests that v2 @provides directive reduces round trips + // - Validates that provided fields are correctly included createTest( /* GraphQL */ ` query { diff --git a/src/test-suites/parent-entity-call-complex/README.md b/src/test-suites/parent-entity-call-complex/README.md new file mode 100644 index 00000000..cf094c3e --- /dev/null +++ b/src/test-suites/parent-entity-call-complex/README.md @@ -0,0 +1,80 @@ +# Parent Entity Call Complex + +## Overview +This test suite validates complex scenarios where child entities need to access data from their parent entities during field resolution, testing the gateway's ability to handle sophisticated entity relationship patterns. + +## Apollo Federation Concepts Tested +- **Complex entity relationships**: Parent-child entity dependencies +- **Multi-hop entity resolution**: Resolving entities that depend on other entities +- **Cross-subgraph data flow**: Information flowing between multiple subgraphs +- **Computed fields with dependencies**: Fields that compute values based on parent entity data +- **Entity resolution chaining**: Following entity relationships across multiple resolution steps + +## Test Scenario +The test involves a complex relationship between Product and Category entities: + +1. **Product Entity**: + - Has an `id` and `name` field + - References a Category entity + - Product data is distributed across multiple subgraphs + +2. **Category Entity**: + - Has `id`, `name`, and computed `details` field + - The `details` field computation depends on the parent Product's `name` + - Category data is also distributed across subgraphs + +3. **Complex Resolution Chain**: + - Query starts from subgraph D + - Product name is resolved from one subgraph + - Category name is resolved from another subgraph + - Category details is computed using the Product name + +## Test Case + +### Multi-Subgraph Parent-Child Resolution +- Tests a query that traverses Product → Category relationship +- Verifies that the Category's `details` field can access the parent Product's `name` +- Validates that complex entity resolution chains work correctly +- Ensures that data flows properly between parent and child entities across subgraphs + +The expected result shows that the Category's details field contains "Details for Product#1", demonstrating that the child entity successfully accessed the parent's name for computation. + +## What's Being Tested + +### Advanced Entity Resolution +1. **Parent-Child Dependencies**: Child entities can access parent entity data for field resolution +2. **Multi-Hop Resolution**: Resolving entities that depend on previously resolved entities +3. **Cross-Subgraph Data Flow**: Information properly flows between subgraphs in complex scenarios + +### Computed Field Patterns +1. **Dynamic Computation**: Fields computed based on runtime data from other entities +2. **Context Propagation**: Parent entity context is available to child entity resolvers +3. **Dependency Resolution**: The gateway resolves dependencies in the correct order + +### Federation Complexity +1. **Query Planning**: The gateway can plan complex queries with entity dependencies +2. **Execution Order**: Field resolution happens in the correct sequence +3. **Performance**: Complex resolution patterns don't cause performance issues + +## Why This Matters +Complex parent-child entity patterns are important for: +- **Real-World Scenarios**: Many applications have sophisticated entity relationships +- **Business Logic**: Complex business rules often require access to related entity data +- **Data Consistency**: Ensuring computed fields have access to all necessary context +- **Performance Optimization**: Efficient resolution of complex entity graphs + +## Common Use Cases +This pattern appears in scenarios like: +- **Product Catalogs**: Where product details depend on category information +- **User Profiles**: Where profile fields depend on account or preference data +- **Order Processing**: Where line items need access to order-level information +- **Content Management**: Where content fields depend on publication or author data + +## Implementation Challenges +Gateways must handle: +- **Resolution Ordering**: Ensuring parent entities are resolved before dependent children +- **Context Passing**: Making parent entity data available to child resolvers +- **Query Planning**: Optimizing queries to minimize round trips while maintaining dependencies +- **Error Handling**: Gracefully handling cases where parent entity resolution fails + +This test ensures that federated gateways can handle sophisticated real-world entity relationship patterns that are common in complex applications. \ No newline at end of file diff --git a/src/test-suites/parent-entity-call-complex/test.ts b/src/test-suites/parent-entity-call-complex/test.ts index 716d53be..3a80b29b 100644 --- a/src/test-suites/parent-entity-call-complex/test.ts +++ b/src/test-suites/parent-entity-call-complex/test.ts @@ -1,6 +1,13 @@ import { createTest } from "../../testkit.js"; export default [ + // Test complex parent entity resolution with computed fields + // Verifies that entities can resolve fields that depend on data from parent entities + // - productFromD query starts from subgraph D + // - Product entity gets name from one subgraph + // - Category entity gets name and details from different subgraphs + // - details field is computed based on the product name + // This tests complex federation scenarios where child entities need parent data createTest( /* GraphQL */ ` query { diff --git a/src/test-suites/simple-inaccessible/README.md b/src/test-suites/simple-inaccessible/README.md new file mode 100644 index 00000000..f9591c12 --- /dev/null +++ b/src/test-suites/simple-inaccessible/README.md @@ -0,0 +1,77 @@ +# Simple Inaccessible + +## Overview +This test suite validates the `@inaccessible` directive in Apollo Federation, which allows schema elements to be hidden from the public API while still being available for internal federation operations. + +## Apollo Federation Concepts Tested +- **@inaccessible directive**: Hiding fields, types, and enum values from the public schema +- **Schema composition**: How inaccessible elements affect schema merging +- **Field resolution**: How inaccessible fields behave during query execution +- **Error handling**: Validation errors when accessing inaccessible elements +- **Enum value filtering**: Hiding specific enum values while keeping others accessible + +## Test Scenario +The test involves a User entity with friend relationships: + +1. **Age Subgraph**: + - Defines User entity with basic fields + - Provides a clean query interface without inaccessible elements + +2. **Friends Subgraph**: + - Extends User with friends field that has an inaccessible default argument + - Defines FriendType enum with FAMILY value marked as @inaccessible + - Contains User.type field that returns the inaccessible enum value + +## Test Cases + +### 1. Normal Operation with Inaccessible Elements Present +- Tests that regular queries work normally when the schema contains @inaccessible elements +- Verifies that inaccessible elements don't break standard query execution +- Ensures that federation still works correctly with hidden schema elements + +### 2. Query from Subgraph with Inaccessible Elements +- Tests queries originating from a subgraph that contains @inaccessible elements +- Verifies that the presence of inaccessible elements in a subgraph doesn't affect query execution +- Demonstrates that inaccessible elements are implementation details + +### 3. Error Handling for Inaccessible Arguments +- Tests that using inaccessible enum values in arguments results in validation errors +- Verifies that the gateway properly enforces inaccessible restrictions +- Ensures that clients cannot access hidden schema elements even if they know about them + +### 4. Null Return for Inaccessible Values +- Tests that fields returning inaccessible enum values return null +- Verifies that inaccessible elements are filtered from responses +- Demonstrates how the gateway handles inaccessible data gracefully + +## What's Being Tested + +### Schema Hiding +1. **Element Filtering**: Inaccessible elements are properly hidden from the public schema +2. **Validation**: Attempts to use inaccessible elements result in validation errors +3. **Response Filtering**: Inaccessible values are filtered from query responses + +### Federation Integration +1. **Internal Operations**: Inaccessible elements can still be used for internal federation logic +2. **Schema Composition**: Inaccessible elements don't interfere with schema merging +3. **Query Planning**: The gateway can still plan queries despite hidden elements + +### Runtime Behavior +1. **Error Handling**: Proper validation errors for inaccessible element usage +2. **Null Handling**: Graceful handling of inaccessible values in responses +3. **Performance**: No performance penalty for having inaccessible elements + +## Why This Matters +The `@inaccessible` directive is important for: +- **API Evolution**: Hiding deprecated or experimental fields from public APIs +- **Internal Fields**: Keeping federation-specific fields hidden from clients +- **Schema Cleanup**: Removing clutter from public schemas while maintaining functionality +- **Gradual Migration**: Hiding fields during migration periods without breaking federation + +## Implementation Notes +Different gateways may handle @inaccessible differently: +- **Schema Level**: Remove inaccessible elements from the composed schema +- **Runtime Level**: Filter inaccessible elements during query execution +- **Validation Level**: Prevent queries from accessing inaccessible elements + +This test ensures that gateways properly implement the @inaccessible directive and handle edge cases appropriately. \ No newline at end of file diff --git a/src/test-suites/simple-inaccessible/test.ts b/src/test-suites/simple-inaccessible/test.ts index 7810085e..dacd3094 100644 --- a/src/test-suites/simple-inaccessible/test.ts +++ b/src/test-suites/simple-inaccessible/test.ts @@ -1,6 +1,10 @@ import { createTest } from "../../testkit.js"; export default [ + // Test basic query functionality with @inaccessible fields present + // Verifies that users can be queried and their friends resolved normally + // when the schema contains @inaccessible fields and enum values + // - The query works because it doesn't access any @inaccessible elements createTest( /* GraphQL */ ` query { @@ -35,6 +39,10 @@ export default [ }, }, ), + // Test query from friends subgraph that contains @inaccessible fields + // Verifies that queries work normally even when executed from subgraphs + // that have @inaccessible field arguments and enum values + // - usersInFriends query should work despite the subgraph having @inaccessible elements createTest( /* GraphQL */ ` query { @@ -69,6 +77,10 @@ export default [ }, }, ), + // Test that @inaccessible field arguments cannot be used + // Verifies that attempting to use @inaccessible argument values results in an error + // - friends(type: FRIEND) should fail because FAMILY enum value is @inaccessible + // - This tests that the gateway properly enforces @inaccessible restrictions createTest( /* GraphQL */ ` query { @@ -84,6 +96,10 @@ export default [ errors: true, }, ), + // Test that @inaccessible fields return null when accessed + // Verifies that fields marked @inaccessible are present in the schema but return null + // - type field should return null because it uses the @inaccessible FAMILY enum value + // - This demonstrates how @inaccessible affects field resolution createTest( /* GraphQL */ ` query {