diff --git a/e2e/_api/graphql.mjs b/e2e/_api/graphql.mjs index f5fd58d758..546e320add 100644 --- a/e2e/_api/graphql.mjs +++ b/e2e/_api/graphql.mjs @@ -54,7 +54,7 @@ let cities = [ ] // example data -const data = [ +const _data = [ { id: '1', name: 'Bruce Willis', birthDate: new Date(1955, 2, 19) }, { id: '2', name: 'Samuel Jackson', birthDate: new Date(1948, 11, 21) }, { id: '3', name: 'Morgan Freeman', birthDate: new Date(1937, 5, 0) }, @@ -66,7 +66,7 @@ const data = [ ] const snapshots = {} -function getSnapshot(snapshot) { +function getSnapshot(snapshot, data = _data) { if (!snapshots[snapshot]) { snapshots[snapshot] = data.map((user) => ({ ...user, @@ -88,6 +88,12 @@ async function processFile(file) { }) } +// example union data +const unionData = [ + { __typename: 'ModelA', id: 'm1', data: { x: 1, y: 2 } }, + { __typename: 'ModelB', id: 'm2', data: { msg: "ok" } }, +] + export const resolvers = { Query: { hello: () => { @@ -137,7 +143,10 @@ export const resolvers = { } return user }, - avgYearsBirthDate: () => { + modelsConnection(_, args) { + return connectionFromArray(getSnapshot(args.snapshot, unionData), args) + }, + avgYearsBirthDate: () => { return list.map((c) => c.birthDate.getFullYear()).reduce((a, b) => a + b) / list.length }, node(_, { id: nodeID }) { diff --git a/e2e/_api/schema.graphql b/e2e/_api/schema.graphql index 4753c771ab..f870d40bcd 100644 --- a/e2e/_api/schema.graphql +++ b/e2e/_api/schema.graphql @@ -58,6 +58,13 @@ type Query { ): UserConnection! usersList(limit: Int = 4, offset: Int, snapshot: String!): [User!]! userNodes(limit: Int = 4, offset: Int, snapshot: String!): UserNodes! + modelsConnection( + after: String + before: String + first: Int + last: Int + snapshot: String! + ): ModelConnection! session: String cities: [City]! } @@ -107,3 +114,32 @@ type City { name: String! libraries: [Library]! } + +type ModelAData { + x: Float! + y: Float! +} + +type ModelA { + data: ModelAData +} + +type ModelBData { + msg: String +} + +type ModelB { + data: ModelBData +} + +union Model = ModelA | ModelB + +type ModelEdge { + cursor: String + node: Model +} + +type ModelConnection { + edges: [ModelEdge!]! + pageInfo: PageInfo! +} diff --git a/e2e/sveltekit/src/lib/utils/routes.ts b/e2e/sveltekit/src/lib/utils/routes.ts index 3bbba8b1fb..d4b042966a 100644 --- a/e2e/sveltekit/src/lib/utils/routes.ts +++ b/e2e/sveltekit/src/lib/utils/routes.ts @@ -36,6 +36,7 @@ export const routes = { Plugin_query_variable_error: '/plugin/query/variables-error', Plugin_query_multiple: '/plugin/query/multiple', Plugin_query_scalars: '/plugin/query/scalars', + Plugin_query_union: '/plugin/query/union', Plugin_query_component: '/plugin/query/component', Plugin_query_beforeLoad: '/plugin/query/beforeLoad', Plugin_query_afterLoad: '/plugin/query/afterLoad', diff --git a/e2e/sveltekit/src/routes/plugin/query/union/+page.svelte b/e2e/sveltekit/src/routes/plugin/query/union/+page.svelte new file mode 100644 index 0000000000..6fbc1335bf --- /dev/null +++ b/e2e/sveltekit/src/routes/plugin/query/union/+page.svelte @@ -0,0 +1,40 @@ + + +{#if $result.data?.modelsConnection?.edges} + {#each $result.data?.modelsConnection.edges as edge} + {#if edge.node.__typename === "ModelA"} +
+ x: {edge.node.data?.x} +
+ {:else if edge.node.__typename === "ModelB"} +
+ msg: {edge.node.data?.msg} +
+ {/if} + {/each} +{/if} diff --git a/e2e/sveltekit/src/routes/plugin/query/union/spec.ts b/e2e/sveltekit/src/routes/plugin/query/union/spec.ts new file mode 100644 index 0000000000..0e1fe7befe --- /dev/null +++ b/e2e/sveltekit/src/routes/plugin/query/union/spec.ts @@ -0,0 +1,26 @@ +import { routes } from '../../../../lib/utils/routes.js'; +import { + expectToBe, + goto, + navSelector, + clientSideNavigation, + expect_0_gql +} from '../../../../lib/utils/testsHelper.js'; +import { test } from '@playwright/test'; + +test.describe('query preprocessor unions', () => { + test('query arrays with unions get unmarshaled into different types', async function ({ page }) { + await goto(page, routes.Plugin_query_union); + await clientSideNavigation(page, routes.Home); + + // We want the query in the frontend, so we navigate to the page + // to zoom on union test & data + await expect_0_gql(page, navSelector(routes.Plugin_query_union)); + + // Expect first type data to be set + await expectToBe(page, 'x: 1', 'div[id=result-union-model-a]'); + + // Expect second type data to be set + await expectToBe(page, 'msg: ok', 'div[id=result-union-model-b]'); + }); +});