You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There were a few things that didn't worked as expected or weren't validated correctly in the handling of `@interfaceObject` and this commit fixes those issues. The issues concretely fixed are:
- Proper validation of shareability for fields provided by @interfaceObject, including cases where multiple @interfaceObject "abstract" the same field.
- If `@interfaceObject` is used for some interface `I`, reject if the subgraph also defines some of the implementations of `I` (this may be something that we lift later, but since the `@interfaceObject` abstract the type in question, we should take some time to think about the consequence if we do lift that limitation).
- Rejects `@override` on both `@interfaceObject` fields and object type fields which are otherwise provided by an @interfaceObject in another subgraph. Here again, we can probably lift such limitation later, but we need to think that through.
- Fix handling of external fields on implementation type when those field are provided by an `@interfaceObject`. This was preventing using such fields in `@requires` for instance.
- Rejects `@override` when used on interface fields. This is actually not strictly `@interfaceObject` related, but simply noticed that we were not properly rejecting it (much like we didn't reject `@shareable` on interface fields until a recent fix). The code definitively does not handle `@override` on an interface field (and like for `@shareable`, it's a tad unclear what it would mean really), and accepting it while ignoring it is just confusing.
// (definition and extension) but also that it's properly taking into account.
2114
2114
assertCompositionSuccess(result);
2115
2115
});
2116
+
2117
+
describe('@interfaceObject',()=>{
2118
+
// An @interfaceObject type provides fields for all the implementation it abstracts, which should impact the shareability
2119
+
// for those concrete impelmentations. That is, if a field is provided by both an @interfaceObject and also by one concrete
2120
+
// implementation in another subgraph, then it needs to be marked @shareable. Those test check this as well as some
2121
+
// variants.
2122
+
2123
+
it.each([
2124
+
{
2125
+
shareableOnConcreteType: false,
2126
+
shareableOnInterfaceObject: false,
2127
+
nonShareableErrorDetail: 'all of them',
2128
+
},
2129
+
{
2130
+
shareableOnConcreteType: true,
2131
+
shareableOnInterfaceObject: false,
2132
+
nonShareableErrorDetail: 'subgraph "subgraphA" (through @interfaceObject field "I.x")',
2133
+
},
2134
+
{
2135
+
shareableOnConcreteType: false,
2136
+
shareableOnInterfaceObject: true,
2137
+
nonShareableErrorDetail: 'subgraph "subgraphB"',
2138
+
},
2139
+
{
2140
+
shareableOnConcreteType: true,
2141
+
shareableOnInterfaceObject: true,
2142
+
},
2143
+
])(
2144
+
'enforces shareable constraints for field "abstracted" by @interfaceObject and shared (shareable on concrete type: $shareableOnConcreteType, shareable on @interfaceObject: $shareableOnInterfaceObject)',
`Non-shareable field "A.x" is resolved from multiple subgraphs: it is resolved from subgraphs "subgraphA" (through @interfaceObject field "I.x") and "subgraphB" and defined as non-shareable in ${nonShareableErrorDetail}`
2185
+
]]);
2186
+
}else{
2187
+
expect(result.errors).toBeUndefined();
2188
+
}
2189
+
}
2190
+
);
2191
+
2192
+
it.each([
2193
+
{
2194
+
shareableOnI1: false,
2195
+
shareableOnI2: false,
2196
+
nonShareableErrorDetail: 'all of them',
2197
+
},
2198
+
{
2199
+
shareableOnI1: true,
2200
+
shareableOnI2: false,
2201
+
nonShareableErrorDetail: 'subgraph "subgraphA" (through @interfaceObject field "I2.x")',
2202
+
},
2203
+
{
2204
+
shareableOnI1: false,
2205
+
shareableOnI2: true,
2206
+
nonShareableErrorDetail: 'subgraph "subgraphA" (through @interfaceObject field "I1.x")',
2207
+
},
2208
+
{
2209
+
shareableOnI1: true,
2210
+
shareableOnI2: true,
2211
+
},
2212
+
])(
2213
+
'enforces shareability in a single subgraph with 2 intersecting @interfaceObject (shareable on first @interfaceObject: $shareableOnI1, shareable on second @interfaceObject: $shareableOnI2)',
`Non-shareable field "A.x" is resolved from multiple subgraphs: it is resolved from subgraphs "subgraphA" (through @interfaceObject field "I1.x") and "subgraphA" (through @interfaceObject field "I2.x") and defined as non-shareable in ${nonShareableErrorDetail}`
'[subgraphA] Interface type "I" has a resolvable key (@key(fields: "id")) in subgraph "subgraphA" but that subgraph is missing some of the supergraph implementation types of "I". Subgraph "subgraphA" should define type "C" (and have it implement "I").',
3545
3699
]]);
3546
3700
});
3701
+
3702
+
it('errors if a subgraph defines both an @interfaceObject and some implemenations',()=>{
'[subgraphB] Interface type "I" is defined as an @interfaceObject in subgraph "subgraphB" so that subgraph should not define any of the implementation types of "I", but it defines type "A"',
'Invalid @override on field "A.a" of subgraph "Subgraph2": source subgraph "Subgraph1" does not have field "A.a" but abstract it in type "I" and overriding abstracted fields is not supported.',
0 commit comments