Skip to content

Commit

Permalink
follow up re: @mike-plummer review
Browse files Browse the repository at this point in the history
  • Loading branch information
tgriesser committed Jun 28, 2022
1 parent ec55561 commit 2802981
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
31 changes: 29 additions & 2 deletions packages/frontend-shared/cypress/e2e/e2ePluginSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,30 @@ async function makeE2ETasks () {
const keys: string[] = []
const values: Promise<any>[] = []
const finalVal: Record<string, any> = {}

const errors: GraphQLError[] = []

// The batch execution plugin (https://www.graphql-tools.com/docs/batch-execution) batches the
// query variables & payloads by rewriting both the fields & variables to ensure there
// are no collisions. It does so in a consistent manner, prefixing each field with an incrementing integer,
// and prefixing the variables within that selection set with the same id
//
// It ends up looking something like this:
//
// query ($_0_variableA: String, $_0_variableB: String, $_1_variableA: String, $_1_variableB: String) {
// _0_someQueryField: someQueryField(argA: $_0_variableA) {
// id
// field(argB: $_0_variableB))
// }
// _1_someQueryField: someQueryField(argA: $_1_variableA) {
// id
// field(argB: $_1_variableB))
// }
// }
//
// To make it simpler to test, we take this knowledge and use some regexes & rewriting it to parse out the index,
// and re-write the variables as though we were executing the query individually, the same way the plugin does when
// we return the resolved data. We then expect that you return the data for the individual row
//
for (const [key, val] of Object.entries(result.data as Record<string, any>)) {
const re = /^_(\d+)_(.*?)$/.exec(key)

Expand All @@ -244,11 +267,15 @@ async function makeE2ETasks () {
variables: subqueryVariables,
result: result[key],
}, testState)
}).catch((e) => {
errors.push(new GraphQLError(e.message, undefined, undefined, undefined, [key], e))

return null
}))
}
result = {
data: _.zipObject(keys, (await Promise.allSettled(values)).map((v) => v.status === 'fulfilled' ? v.value : v.reason)),
errors: result.errors,
errors: errors.length ? [...(result.errors ?? []), ...errors] : result.errors,
extensions: result.extensions,
}
} else if (remoteGraphQLIntercept) {
Expand Down
10 changes: 5 additions & 5 deletions packages/frontend-shared/cypress/e2e/support/e2eSupport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ export interface RemoteGraphQLBatchInterceptPayload {
result: ExecutionResult
}

export type RemoteGraphQLInterceptor = (obj: RemoteGraphQLInterceptPayload, testState: Record<string, any>) => ExecutionResult | Promise<ExecutionResult> | Response
export type RemoteGraphQLInterceptor <T = {[key: string]: any}> = (obj: RemoteGraphQLInterceptPayload, testState: Record<string, any>) => ExecutionResult<T> | Promise<ExecutionResult<T>> | Response

export type RemoteGraphQLBatchInterceptor = (obj: RemoteGraphQLBatchInterceptPayload, testState: Record<string, any>) => any | Promise<any>
export type RemoteGraphQLBatchInterceptor<T = any> = (obj: RemoteGraphQLBatchInterceptPayload, testState: Record<string, any>) => T | Promise<T>

export interface FindBrowsersOptions {
// Array of FoundBrowser objects that will be used as the mock output
Expand Down Expand Up @@ -144,7 +144,7 @@ declare global {
*/
remoteGraphQLIntercept: typeof remoteGraphQLIntercept
/**
* Gives the ability to intercept the remote GraphQL request & respond accordingly
* Gives the ability to intercept the batched remote GraphQL request & respond accordingly
*/
remoteGraphQLInterceptBatched: typeof remoteGraphQLInterceptBatched
/**
Expand Down Expand Up @@ -452,13 +452,13 @@ function findBrowsers (options: FindBrowsersOptions = {}) {
})
}

function remoteGraphQLIntercept (fn: RemoteGraphQLInterceptor) {
function remoteGraphQLIntercept <T = any> (fn: RemoteGraphQLInterceptor<T>) {
return logInternal('remoteGraphQLIntercept', () => {
return taskInternal('__internal_remoteGraphQLIntercept', fn.toString())
})
}

function remoteGraphQLInterceptBatched (fn: RemoteGraphQLBatchInterceptor) {
function remoteGraphQLInterceptBatched <T = any> (fn: RemoteGraphQLBatchInterceptor<T>) {
return logInternal('remoteGraphQLInterceptBatched', () => {
return taskInternal('__internal_remoteGraphQLInterceptBatched', fn.toString())
})
Expand Down

0 comments on commit 2802981

Please sign in to comment.