@apollo/client/link/context#setContext TypeScript Examples

The following examples show how to use @apollo/client/link/context#setContext. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: client.ts    From ui with GNU Affero General Public License v3.0 6 votes vote down vote up
getClient = (): ApolloClient<NormalizedCacheObject> => {
  if (!client) {
    const config = getConfig() as NextConfigType

    if (!config) return client

    const { publicRuntimeConfig, serverRuntimeConfig } = config

    client = new ApolloClient<NormalizedCacheObject>({
      cache: new InMemoryCache(),
      link: from([
        setContext((request, context) => {
          const headers: { [key: string]: string } = {}

          if (process.browser) {
            const access = localStorage.getItem('access')

            if (access) {
              headers.authorization = `Bearer ${access}`
            }
          }

          return {
            headers,
          }
        }),
        new HttpLink({
          uri: serverRuntimeConfig.endpoint || publicRuntimeConfig.endpoint,
        }),
      ]),
    })
  }

  return client
}
Example #2
Source File: clientConfig.ts    From OpenVolunteerPlatform with MIT License 6 votes vote down vote up
authLink = setContext(async (_, { headers }) => {
  return {
    headers: {
      ...headers,
      // returns auth header or empty string
      ...await getAuthHeader()
    }
  }
})
Example #3
Source File: configured-command.ts    From amplication with Apache License 2.0 6 votes vote down vote up
constructor(...args: [any, any]) {
    super(...args);

    if (!fs.existsSync(this.config.configDir))
      fs.mkdirSync(this.config.configDir, { recursive: true });

    if (fs.existsSync(this.configFilePath))
      this.configJSON = require(this.configFilePath);

    let serverUrl = this.configJSON[AMP_SERVER_URL];
    if (!serverUrl) {
      serverUrl = DEFAULT_SERVER_URL;
      this.setConfig(AMP_SERVER_URL, DEFAULT_SERVER_URL);
    }

    serverUrl = urlJoin(serverUrl, 'graphql');
    const httpLink = createHttpLink({
      uri: serverUrl,
      fetch,
    });

    const authLink = setContext((_, { headers }) => {
      // get the authentication token from config if it exists
      const token = this.getConfig('token');
      // return the headers to the context so httpLink can read them
      return {
        headers: {
          ...headers,
          authorization: token ? `Bearer ${token}` : '',
        },
      };
    });

    this.client.setLink(authLink.concat(httpLink));
  }
Example #4
Source File: index.tsx    From amplication with Apache License 2.0 6 votes vote down vote up
authLink = setContext((_, { headers }) => {
  // get the authentication token from local storage if it exists
  const token = getToken();
  // return the headers to the context so httpLink can read them
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : "",
    },
  };
})
Example #5
Source File: graphqlDataProvider.ts    From amplication with Apache License 2.0 6 votes vote down vote up
authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem(CREDENTIALS_LOCAL_STORAGE_ITEM);
  return {
    headers: {
      ...headers,
      authorization: token ? token : "",
    },
  };
})
Example #6
Source File: withData.tsx    From keycapsets.com with GNU General Public License v3.0 6 votes vote down vote up
authLink = setContext((_, { headers }) => {
    if (typeof window !== 'undefined') {
        token = localStorage.getItem('TOKEN');
    }

    return {
        headers: {
            ...headers,
            authorization: token ? `Bearer ${token}` : null,
        },
    };
})
Example #7
Source File: index.tsx    From tinyhouse with MIT License 6 votes vote down vote up
authLink = setContext((_, { headers }) => {
    const token = sessionStorage.getItem("token");
    return {
        headers: {
            ...headers,
            "X-CSRF-TOKEN": token || "",
        },
    };
})
Example #8
Source File: apollo.ts    From HoldemSolver with MIT License 6 votes vote down vote up
authLink = setContext((_, { headers }) => {
    // get the authentication token from local storage if it exists
    const token = localStorage.getItem('jwt');
    if (token) {
        return {
            headers: {
                ...headers,
                authorization: token
            }
        };
    }
    return headers;
})
Example #9
Source File: index.tsx    From ledokku with MIT License 6 votes vote down vote up
authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem('accessToken');
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : '',
    },
  };
})
Example #10
Source File: client.ts    From lexicon with MIT License 6 votes vote down vote up
authLink = setContext(async (_, { headers }) => {
  const token = await getToken();
  return {
    headers: {
      ...headers,
      Authorization: token,
    },
  };
})
Example #11
Source File: api.service.ts    From etherspot-sdk with MIT License 5 votes vote down vote up
protected onInit(): void {
    const httpLink = new HttpLink({
      fetch,
      uri: buildApiUri(this.options, 'http'),
    });

    const wsLink = new WebSocketLink({
      webSocketImpl: WebSocket,
      uri: buildApiUri(this.options, 'ws', 'graphql'),
      options: {
        reconnect: true,
        lazy: true,
      },
    });

    const authLink = setContext(async () => {
      const {
        accountService, //
        sessionService,
        projectService,
      } = this.services;

      return {
        headers: {
          ...accountService.headers,
          ...sessionService.headers,
          ...projectService.headers,
        },
      };
    });

    const link = split(
      // split based on operation type
      ({ query }) => {
        const definition = getMainDefinition(query);
        return definition.kind === 'OperationDefinition' && definition.operation === 'subscription';
      },
      wsLink,
      authLink.concat(httpLink),
    );

    this.apolloClient = new ApolloClient({
      link,
      cache: this.cache,
    });
  }
Example #12
Source File: client.ts    From magento_react_native_graphql with MIT License 5 votes vote down vote up
export async function getApolloClient(): Promise<ApolloClient<any>> {
  if (_client) {
    return _client;
  }

  const cache = new InMemoryCache({
    possibleTypes,
    typePolicies: {
      Query: {
        fields: {
          products: {
            // Cache separate results based on
            // any of this field's arguments.
            keyArgs: ['search', 'filter'],
            // Concatenate the incoming list items with
            // the existing list items.
            merge(existing, incoming, { args: { currentPage } }) {
              if (currentPage === 1) {
                return incoming;
              }
              const _existing = existing ?? { items: [] };
              const _incoming = incoming ?? { items: [] };
              return {
                ..._existing,
                ..._incoming,
                items: [..._existing.items, ..._incoming.items],
              };
            },
          },
        },
      },
    },
  });

  const customerToken = await loadCustomerToken();

  if (customerToken !== null) {
    cache.writeQuery({
      query: IS_LOGGED_IN,
      data: {
        isLoggedIn: true,
      },
    });
  }

  const httpLink = createHttpLink({
    uri: `${magentoConfig.url}/graphql`,
  });

  const authLink = setContext(async (_, { headers }) => {
    // get the authentication token from local storage if it exists
    const token = await loadCustomerToken();
    // return the headers to the context so httpLink can read them
    return {
      headers: {
        ...headers,
        authorization: token !== null ? `Bearer ${token}` : '',
      },
    };
  });

  const client = new ApolloClient({
    link: authLink.concat(httpLink),
    cache,
  });

  _client = client;

  return client;
}
Example #13
Source File: Shell.tsx    From dh-web with GNU General Public License v3.0 5 votes vote down vote up
Shell: FC<ShellProperties> = ({ children }: ShellProperties) => {

    // get the authentication token from local storage if it exists
    const authToken = useSelector(getAuthenticationToken);

    const bearerString = authToken && `Bearer ${authToken}`;
    // cross platform web socketing triage (tldr use node lib on server and web lib on browser)
    const webSocketImplementation = process.browser ? WebSocket : ws;

    const wsLink = new WebSocketLink({
        uri: "wss://api.dogehouse.online/graphql",
        options: {
            reconnect: true,
            lazy: true,
            timeout: 3000,
            connectionParams: {
                authorization: bearerString
            }
        },
        webSocketImpl: webSocketImplementation
    });

    const httpLink = createHttpLink({
        uri: "https://api.dogehouse.online/graphql",
    });

    const authLink = setContext((_, { headers }) => {
        // return the headers to the context so httpLink can read them
        return {
            headers: {
                ...headers,
                authorization: bearerString,
            }
        };
    });

    const splitLink = split(
        ({ query }) => {
            const definition = getMainDefinition(query);
            return (
                definition.kind === "OperationDefinition" &&
                definition.operation === "subscription"
            );
        },
        wsLink,
        (authLink.concat(httpLink)),
    );

    const client = new ApolloClient({
        link: from([errorLink, splitLink]),
        cache: new InMemoryCache(),
    });

    return (
        <ThemeProvider theme={DarkTheme}>
            <ApolloProvider client={client}>
                <GlobalStyle />
                <Head>
                    <link rel="preconnect" href="https://fonts.gstatic.com" />
                    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet" />
                </Head>
                <Wrapper>
                    <NoSsr>
                        {
                            children
                        }
                    </NoSsr>
                </Wrapper>
            </ApolloProvider>
        </ThemeProvider>
    );
}
Example #14
Source File: apolloClient.ts    From bouncecode-cms with GNU General Public License v3.0 5 votes vote down vote up
function createApolloClient(req) {
  const isSsr = typeof window === 'undefined';
  const uri = isSsr ? `http://localhost:${PORT}/graphql` : '/graphql';

  const getToken = async ({access_token, refresh_token}) => {
    if (access_token) {
      try {
        const {exp}: any = jwt.decode(access_token);

        if (Date.now() < (exp - 600) * 1000) {
          return access_token;
        }
      } catch (e) {}
    }

    if (refresh_token) {
      const res = await fetch(uri, {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({
          operationName: null,
          query: gql`
            mutation($refreshToken: String!) {
              refreshToken(refreshToken: $refreshToken) {
                access_token
              }
            }
          `.loc.source.body,
          variables: {
            refreshToken: refresh_token,
          },
        }),
      });

      const {data} = await res.json();
      const access_token = data.token.access_token;
      storeToken(null, {access_token});
      return access_token;
    }
  };

  const httpLink = new HttpLink({
    uri, // Server URL (must be absolute)
    credentials: 'same-origin', // Additional fetch() options like `credentials` or `headers`
    fetch,
  });

  const authLink = setContext(async (_, {headers}) => {
    const {access_token, refresh_token} = parseCookies(req);
    let token;

    try {
      token = await getToken({access_token, refresh_token});
    } catch (e) {}

    if (token) {
      return {
        headers: {
          ...headers,
          authorization: `Bearer ${token}`,
        },
      };
    } else {
      return {headers};
    }
  });

  // The `ctx` (NextPageContext) will only be present on the server.
  // use it to extract auth headers (ctx.req) or similar.
  return new ApolloClient({
    ssrMode: isSsr,
    link: authLink.concat(httpLink),
    cache: new InMemoryCache(),
  });
}
Example #15
Source File: Apollo.ts    From jmix-frontend with Apache License 2.0 5 votes vote down vote up
export function initializeApolloClient<TCacheShape>(config: JmixApolloConfig<TCacheShape> = {}): ApolloClient<TCacheShape> {

  const {
    customApolloOptions = {},
    storage = window.localStorage,
    graphqlEndpoint = '/graphql',
    // TODO Rename to jmixAccessToken once REST is dropped
    tokenStorageKey = 'jmixRestAccessToken',
    localeStorageKey = 'jmixLocale'
  } = config;

  const uploadLink = createUploadLink({
    uri: graphqlEndpoint
  });

  const authLink = setContext((_, { headers }) => {
    const token = storage.getItem(tokenStorageKey);
    const locale = storage.getItem(localeStorageKey);
    return {
      headers: {
        ...headers,
        authorization: token ? `Bearer ${token}` : "",
        'Accept-Language': locale
      }
    };
  });

  return new ApolloClient<TCacheShape>({
    link: authLink.concat(uploadLink),
    cache: new InMemoryCache({
      addTypename: false
    }) as unknown as ApolloCache<TCacheShape>,
    defaultOptions: {
      query: {
        fetchPolicy: 'network-only'
      },
      watchQuery: {
        fetchPolicy: "cache-and-network"
      }
    },
    ...customApolloOptions
  });
}
Example #16
Source File: graphql.module.ts    From one-platform with MIT License 5 votes vote down vote up
auth = setContext( ( operation, context ) => ( {
  headers: {
    Accept: 'charset=utf-8',
    Authorization: ( window as any ).OpAuthHelper?.jwtToken
      ? 'Bearer ' + ( window as any ).OpAuthHelper.jwtToken
      : '',
  },
} ) )
Example #17
Source File: graphql.module.ts    From one-platform with MIT License 4 votes vote down vote up
export function createApollo(): ApolloClientOptions<any> {
  const wsClient = new WebSocketLink({
    uri: environment.WS_URL,
    options: {
      reconnect: true,
      inactivityTimeout: 0,
      reconnectionAttempts: 10,
      connectionParams: {
        Authorization: `Bearer ${window.OpAuthHelper.jwtToken}`,
      },
    },
  });

  const httpLink = createHttpLink({
    uri: environment.API_URL,
  });

  const authLink = setContext((_, { headers }) => {
    // get the authentication token from local storage if it exists
    const token = window.OpAuthHelper.jwtToken;
    // return the headers to the context so httpLink can read them
    return {
      headers: {
        ...headers,
        Authorization: token ? `Bearer ${token}` : '',
      },
    };
  });

  const splitLink = split(
    ({ query }) => {
      const definition = getMainDefinition(query);
      return (
        definition.kind === 'OperationDefinition' &&
        definition.operation === 'subscription'
      );
    },
    wsClient,
    authLink.concat(httpLink)
  );
  const retry = new RetryLink({
    delay: {
      initial: 500,
      max: Infinity,
      jitter: false,
    },
    attempts: {
      max: 5,
      retryIf: (_error, _operation) => !!_error,
    },
  }) as any;

  const error = onError(({ graphQLErrors, networkError }) => {
    if (graphQLErrors) {
      graphQLErrors.map(({ message, locations, path }) =>
        console.log(
          `[GraphQL error]: Message: ${JSON.stringify(
            message
          )}, Location: ${JSON.stringify(locations)}, Path: ${JSON.stringify(
            path
          )}`
        )
      );
    }
    if (networkError && networkError['status'] === 0) {
      this.isCertificateError.next(true);
      console.log(`[Network error]: ${JSON.stringify(networkError)}`);
    }
  });

  const link = WebSocketLink.from([retry, error, splitLink]);

  return {
    name: 'Lighthouse GraphQL Client',
    version: '0.0.1',
    link,
    cache: new InMemoryCache({
      addTypename: false,
    }),
    defaultOptions: {
      watchQuery: {
        fetchPolicy: 'cache-and-network',
        errorPolicy: 'all',
      },
    },
  };
}
Example #18
Source File: data-service-generator.e2e-spec.ts    From amplication with Apache License 2.0 4 votes vote down vote up
describe("Data Service Generator", () => {
  let dockerComposeOptions: compose.IDockerComposeOptions;
  let port: number;
  let host: string;
  let customer: { id: string };
  let apolloClient: ApolloClient<any>;
  beforeAll(async () => {
    const directory = path.join(os.tmpdir(), "test-data-service");

    // Clean the temporary directory
    try {
      await fs.promises.rm(directory, { recursive: true });
    } catch {}
    await fs.promises.mkdir(directory);

    // Generate the test data service
    await generateTestDataService(directory, appInfo);

    port = await getPort();
    const dbPort = await getPort();
    host = `http://0.0.0.0:${port}`;

    const authLink = setContext((_, { headers }) => ({
      headers: {
        ...headers,
        authorization: APP_BASIC_AUTHORIZATION,
      },
    }));

    const errorLink = onError(({ graphQLErrors, networkError }) => {
      if (graphQLErrors)
        graphQLErrors.map(({ message, locations, path }) =>
          console.log(
            `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
          )
        );

      if (networkError) console.log(`[Network error]: ${networkError}`);
    });

    const httpLink = createHttpLink({
      uri: `${host}/graphql`,
      fetch,
    });

    apolloClient = new ApolloClient({
      link: authLink.concat(errorLink).concat(httpLink),
      cache: new InMemoryCache(),
    });

    dockerComposeOptions = {
      cwd: directory,
      log: true,
      composeOptions: ["--project-name=e2e"],
      env: {
        ...process.env,
        POSTGRESQL_USER: POSTGRESQL_USER,
        POSTGRESQL_PASSWORD: POSTGRESQL_PASSWORD,
        POSTGRESQL_PORT: String(dbPort),
        SERVER_PORT: String(port),
        BCRYPT_SALT: "10",
        // See: https://www.docker.com/blog/faster-builds-in-compose-thanks-to-buildkit-support/
        COMPOSE_DOCKER_CLI_BUILD: "1",
        DOCKER_BUILDKIT: "1",
        JWT_SECRET_KEY: "Change_ME!!!",
        JWT_EXPIRATION: "2d",
      },
    };

    // Cleanup Docker Compose before run
    await down(dockerComposeOptions);

    await compose.upAll({
      ...dockerComposeOptions,
      commandOptions: ["--build", "--force-recreate"],
    });

    compose.logs([], { ...dockerComposeOptions, follow: true });

    console.info("Waiting for server to be ready...");
    await sleep(SERVER_START_TIMEOUT);
  });

  afterAll(async () => {
    await down(dockerComposeOptions);
  });
  test("check /api/health/live endpoint", async () => {
    const res = await fetch(`${host}/api/health/live`, {
      method: "GET",
    });
    expect(res.status === STATUS_OK);
  });

  test("check api/health/ready endpoint", async () => {
    const res = await fetch(`${host}/api/health/ready`, {
      method: "GET",
    });
    expect(res.status === STATUS_OK);
  });

  test("creates POST /api/login endpoint", async () => {
    const res = await fetch(`${host}/api/login`, {
      method: "POST",
      headers: {
        "Content-Type": JSON_MIME,
      },
      body: JSON.stringify({
        username: APP_USERNAME,
        password: APP_PASSWORD,
      }),
    });
    expect(res.status === STATUS_CREATED);
    expect(await res.json()).toEqual(
      expect.objectContaining({
        username: APP_USERNAME,
        roles: APP_DEFAULT_USER_ROLES,
      })
    );
  });

  test("creates POST /api/customers endpoint", async () => {
    const res = await fetch(`${host}/api/customers`, {
      method: "POST",
      headers: {
        "Content-Type": JSON_MIME,
        Authorization: APP_BASIC_AUTHORIZATION,
      },
      body: JSON.stringify(EXAMPLE_CUSTOMER),
    });
    expect(res.status === STATUS_CREATED);
    customer = await res.json();
    expect(customer).toEqual(
      expect.objectContaining({
        ...EXAMPLE_CUSTOMER,
        id: expect.any(String),
        createdAt: expect.any(String),
        updatedAt: expect.any(String),
      })
    );
  });

  test("creates PATCH /api/customers/:id endpoint", async () => {
    const customer = await (
      await fetch(`${host}/api/customers`, {
        method: "POST",
        headers: {
          "Content-Type": JSON_MIME,
          Authorization: APP_BASIC_AUTHORIZATION,
        },
        body: JSON.stringify(EXAMPLE_CUSTOMER),
      })
    ).json();
    const res = await fetch(`${host}/api/customers/${customer.id}`, {
      method: "PATCH",
      headers: {
        "Content-Type": JSON_MIME,
        Authorization: APP_BASIC_AUTHORIZATION,
      },
      body: JSON.stringify(EXAMPLE_CUSTOMER_UPDATE),
    });
    expect(res.status === STATUS_OK);
  });

  test("handles PATCH /api/customers/:id for a non-existing id", async () => {
    const id = "nonExistingId";
    const res = await fetch(`${host}/api/customers/${id}`, {
      method: "PATCH",
      headers: {
        "Content-Type": JSON_MIME,
        Authorization: APP_BASIC_AUTHORIZATION,
      },
      body: JSON.stringify(EXAMPLE_CUSTOMER_UPDATE),
    });
    expect(res.status === NOT_FOUND);
  });

  test("creates DELETE /api/customers/:id endpoint", async () => {
    const customer = await (
      await fetch(`${host}/api/customers`, {
        method: "POST",
        headers: {
          "Content-Type": JSON_MIME,
          Authorization: APP_BASIC_AUTHORIZATION,
        },
        body: JSON.stringify(EXAMPLE_CUSTOMER),
      })
    ).json();
    const res = await fetch(`${host}/api/customers/${customer.id}`, {
      method: "DELETE",
      headers: {
        "Content-Type": JSON_MIME,
        Authorization: APP_BASIC_AUTHORIZATION,
      },
    });
    expect(res.status === STATUS_OK);
  });

  test("handles DELETE /api/customers/:id for a non-existing id", async () => {
    const id = "nonExistingId";
    const res = await fetch(`${host}/api/customers/${id}`, {
      method: "DELETE",
      headers: {
        "Content-Type": JSON_MIME,
        Authorization: APP_BASIC_AUTHORIZATION,
      },
    });
    expect(res.status === NOT_FOUND);
  });

  test("creates GET /api/customers endpoint", async () => {
    const res = await fetch(`${host}/api/customers`, {
      headers: {
        Authorization: APP_BASIC_AUTHORIZATION,
      },
    });
    expect(res.status === STATUS_OK);
    const customers = await res.json();
    expect(customers).toEqual(
      expect.arrayContaining([
        expect.objectContaining({
          ...EXAMPLE_CUSTOMER,
          id: expect.any(String),
          createdAt: expect.any(String),
          updatedAt: expect.any(String),
        }),
      ])
    );
  });

  test("creates GET /api/customers/:id endpoint", async () => {
    const res = await fetch(`${host}/api/customers/${customer.id}`, {
      headers: {
        Authorization: APP_BASIC_AUTHORIZATION,
      },
    });

    expect(res.status === STATUS_OK);
    expect(await res.json()).toEqual(
      expect.objectContaining({
        ...EXAMPLE_CUSTOMER,
        id: expect.any(String),
        createdAt: expect.any(String),
        updatedAt: expect.any(String),
      })
    );
  });

  test("creates POST /api/organizations/:id/customers endpoint", async () => {
    const customer = await (
      await fetch(`${host}/api/customers`, {
        method: "POST",
        headers: {
          "Content-Type": JSON_MIME,
          Authorization: APP_BASIC_AUTHORIZATION,
        },
        body: JSON.stringify(EXAMPLE_CUSTOMER),
      })
    ).json();

    const organization = await (
      await fetch(`${host}/api/organizations`, {
        method: "POST",
        headers: {
          "Content-Type": JSON_MIME,
          Authorization: APP_BASIC_AUTHORIZATION,
        },
        body: JSON.stringify(EXAMPLE_ORGANIZATION),
      })
    ).json();

    const res = await fetch(
      `${host}/api/organizations/${organization.id}/customers`,
      {
        method: "POST",
        headers: {
          "Content-Type": JSON_MIME,
          Authorization: APP_BASIC_AUTHORIZATION,
        },
        body: JSON.stringify([
          {
            id: customer.id,
          },
        ]),
      }
    );
    expect(res.status).toBe(STATUS_CREATED);
    const data = await res.text();
    expect(data).toBe("");
  });

  test("creates DELETE /api/organizations/:id/customers endpoint", async () => {
    const customer = await (
      await fetch(`${host}/api/customers`, {
        method: "POST",
        headers: {
          "Content-Type": JSON_MIME,
          Authorization: APP_BASIC_AUTHORIZATION,
        },
        body: JSON.stringify(EXAMPLE_CUSTOMER),
      })
    ).json();
    const organization = await (
      await fetch(`${host}/api/organizations`, {
        method: "POST",
        headers: {
          "Content-Type": JSON_MIME,
          Authorization: APP_BASIC_AUTHORIZATION,
        },
        body: JSON.stringify(EXAMPLE_ORGANIZATION),
      })
    ).json();

    await fetch(`${host}/api/organizations/${organization.id}/customers`, {
      method: "POST",
      headers: {
        "Content-Type": JSON_MIME,
        Authorization: APP_BASIC_AUTHORIZATION,
      },
      body: JSON.stringify([
        {
          id: customer.id,
        },
      ]),
    });

    const res = await fetch(
      `${host}/api/organizations/${organization.id}/customers`,
      {
        method: "DELETE",
        headers: {
          "Content-Type": JSON_MIME,
          Authorization: APP_BASIC_AUTHORIZATION,
        },
        body: JSON.stringify([
          {
            id: customer.id,
          },
        ]),
      }
    );
    expect(res.status).toBe(STATUS_OK);
    const data = await res.text();
    expect(data).toBe("");
  });

  test("creates GET /api/organizations/:id/customers endpoint", async () => {
    const customer = await (
      await fetch(`${host}/api/customers`, {
        method: "POST",
        headers: {
          "Content-Type": JSON_MIME,
          Authorization: APP_BASIC_AUTHORIZATION,
        },
        body: JSON.stringify(EXAMPLE_CUSTOMER),
      })
    ).json();
    const organization = await (
      await fetch(`${host}/api/organizations`, {
        method: "POST",
        headers: {
          "Content-Type": JSON_MIME,
          Authorization: APP_BASIC_AUTHORIZATION,
        },
        body: JSON.stringify(EXAMPLE_ORGANIZATION),
      })
    ).json();

    await fetch(`${host}/api/organizations/${organization.id}/customers`, {
      method: "POST",
      headers: {
        "Content-Type": JSON_MIME,
        Authorization: APP_BASIC_AUTHORIZATION,
      },
      body: JSON.stringify([
        {
          id: customer.id,
        },
      ]),
    });

    const res = await fetch(
      `${host}/api/organizations/${organization.id}/customers`,
      {
        method: "GET",
        headers: {
          "Content-Type": JSON_MIME,
          Authorization: APP_BASIC_AUTHORIZATION,
        },
      }
    );
    expect(res.status).toBe(STATUS_OK);
    const data = await res.json();
    expect(data).toEqual(
      expect.arrayContaining([
        expect.objectContaining({
          ...EXAMPLE_CUSTOMER,
          id: customer.id,
          createdAt: expect.any(String),
          updatedAt: expect.any(String),
          organization: {
            id: organization.id,
          },
        }),
      ])
    );
  });

  test("adds customers to root query", async () => {
    expect(
      await apolloClient.query({
        query: gql`
          {
            customers(where: {}) {
              id
              createdAt
              updatedAt
              email
              firstName
              lastName
            }
          }
        `,
      })
    ).toEqual(
      expect.objectContaining({
        data: {
          customers: expect.arrayContaining([
            expect.objectContaining({
              ...omit(EXAMPLE_CUSTOMER, ["organization"]),
              id: customer.id,
              createdAt: expect.any(String),
              updatedAt: expect.any(String),
            }),
          ]),
        },
      })
    );
  });

  //TODO add test if not connect to db send api/health/ready status 503
});