Skip to content
This repository has been archived by the owner on Apr 28, 2023. It is now read-only.

Commit

Permalink
tests(subscriptions): refactor tests from apollo to async-iterators
Browse files Browse the repository at this point in the history
  • Loading branch information
MichalLytek authored and sixmen committed Mar 26, 2020
1 parent eb9f8ef commit 23e9b25
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 132 deletions.
238 changes: 154 additions & 84 deletions tests/functional/subscriptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import {
IntrospectionSchema,
TypeKind,
graphql,
subscribe,
ExecutionResult,
execute,
DocumentNode,
} from "graphql";
import { ApolloClient } from "apollo-client";
import gql from "graphql-tag";
import { EventEmitter } from "events";
import { ApolloServer } from "apollo-server";
import { PubSub as LocalPubSub } from "graphql-subscriptions";

import {
Expand All @@ -31,7 +33,7 @@ import {
import { getMetadataStorage } from "../../src/metadata/getMetadataStorage";
import { getSchemaInfo } from "../helpers/getSchemaInfo";
import { getInnerTypeOfNonNullableType, getItemTypeOfList } from "../helpers/getInnerFieldType";
import createWebSocketUtils from "../helpers/subscriptions/createWebSocketGQL";
import sleep from "../helpers/sleep";

describe("Subscriptions", () => {
describe("Schema", () => {
Expand Down Expand Up @@ -125,8 +127,6 @@ describe("Subscriptions", () => {

describe("Functional", () => {
let schema: GraphQLSchema;
let apolloClient: ApolloClient<any>;
let apolloServer: ApolloServer;
const localPubSub: PubSubEngine = new LocalPubSub();

beforeAll(async () => {
Expand Down Expand Up @@ -223,22 +223,37 @@ describe("Subscriptions", () => {
schema = await buildSchema({
resolvers: [SampleResolver],
});

({ apolloClient, apolloServer } = await createWebSocketUtils(schema));
});

afterAll(async () => {
await apolloServer.stop();
});

it("should build schema without errors", async () => {
expect(schema).toBeDefined();
});

async function subscribeOnceAndMutate(options: {
mutation: DocumentNode;
mutationVariables?: object;
subscription: DocumentNode;
subscriptionVariables?: object;
onSubscribedData: (data: any) => void;
}) {
const results = (await subscribe(
schema,
options.subscription,
null,
null,
options.subscriptionVariables,
)) as AsyncIterableIterator<ExecutionResult<any>>;
const onDataPromise = results.next().then(async ({ value }) => {
options.onSubscribedData(value.data);
});
await execute(schema, options.mutation, null, null, options.mutationVariables);
await onDataPromise;
}

it("should successfully get data from subscription after publishing mutation", async () => {
let subscriptionValue!: number;
const testedValue = Math.PI;
const subscriptionQuery = gql`
const subscription = gql`
subscription {
sampleTopicSubscription {
value
Expand All @@ -251,18 +266,21 @@ describe("Subscriptions", () => {
}
`;

apolloClient.subscribe({ query: subscriptionQuery }).subscribe({
next: ({ data }) => (subscriptionValue = data!.sampleTopicSubscription.value),
await subscribeOnceAndMutate({
subscription,
mutation,
onSubscribedData: data => {
subscriptionValue = data.sampleTopicSubscription.value;
},
});
await apolloClient.mutate({ mutation });

expect(subscriptionValue).toEqual(testedValue);
});

it("should successfully get data from subscription using fragments", async () => {
let subscriptionValue!: number;
const testedValue = Math.PI;
const subscriptionQuery = gql`
const subscription = gql`
fragment TestFragment on SampleObject {
value
}
Expand All @@ -278,10 +296,13 @@ describe("Subscriptions", () => {
}
`;

apolloClient.subscribe({ query: subscriptionQuery }).subscribe({
next: ({ data }) => (subscriptionValue = data!.sampleTopicSubscription.value),
await subscribeOnceAndMutate({
subscription,
mutation,
onSubscribedData: data => {
subscriptionValue = data.sampleTopicSubscription.value;
},
});
await apolloClient.mutate({ mutation });

expect(subscriptionValue).toEqual(testedValue);
});
Expand All @@ -301,22 +322,34 @@ describe("Subscriptions", () => {
}
`;

apolloClient.subscribe({ query: subscriptionQuery }).subscribe({
next: ({ data }) => (subscriptionValue = data!.sampleTopicSubscription.value),
});
const subscription = (await subscribe({
schema,
document: subscriptionQuery,
})) as AsyncIterableIterator<ExecutionResult>;
// run subscription in a separate async "thread"
(async () => {
for await (const result of subscription) {
subscriptionValue = result.data!.sampleTopicSubscription.value;
}
})();

await apolloClient.mutate({ mutation, variables: { value: 1.23 } });
await execute({ schema, document: mutation, variableValues: { value: 1.23 } });
await sleep(0);
expect(subscriptionValue).toEqual(1.23);
await apolloClient.mutate({ mutation, variables: { value: 2.37 } });

await execute({ schema, document: mutation, variableValues: { value: 2.37 } });
await sleep(0);
expect(subscriptionValue).toEqual(2.37);
await apolloClient.mutate({ mutation, variables: { value: 4.53 } });

await execute({ schema, document: mutation, variableValues: { value: 4.53 } });
await sleep(0);
expect(subscriptionValue).toEqual(4.53);
});

it("should successfully publish using Publisher injection", async () => {
let subscriptionValue: number;
const testedValue = Math.PI;
const subscriptionQuery = gql`
const subscription = gql`
subscription {
sampleTopicSubscription {
value
Expand All @@ -329,10 +362,13 @@ describe("Subscriptions", () => {
}
`;

apolloClient.subscribe({ query: subscriptionQuery }).subscribe({
next: ({ data }) => (subscriptionValue = data!.sampleTopicSubscription.value),
await subscribeOnceAndMutate({
subscription,
mutation,
onSubscribedData: data => {
subscriptionValue = data.sampleTopicSubscription.value;
},
});
await apolloClient.mutate({ mutation });

expect(subscriptionValue!).toEqual(testedValue);
});
Expand All @@ -357,15 +393,27 @@ describe("Subscriptions", () => {
}
`;

apolloClient.subscribe({ query: subscriptionQuery }).subscribe({
next: ({ data }) => (subscriptionValue = data!.sampleTopicSubscription.value),
});
const subscription = (await subscribe({
schema,
document: subscriptionQuery,
})) as AsyncIterableIterator<ExecutionResult>;
// run subscription in a separate async "thread"
(async () => {
for await (const result of subscription) {
subscriptionValue = result.data!.sampleTopicSubscription.value;
}
})();

await apolloClient.mutate({ mutation: otherTopicMutation, variables: { value: 1.23 } });
await execute({ schema, document: otherTopicMutation, variableValues: { value: 1.23 } });
await sleep(0);
expect(subscriptionValue).toBeUndefined();
await apolloClient.mutate({ mutation: otherTopicMutation, variables: { value: 2.37 } });

await execute({ schema, document: otherTopicMutation, variableValues: { value: 2.37 } });
await sleep(0);
expect(subscriptionValue).toBeUndefined();
await apolloClient.mutate({ mutation: sampleTopicMutation, variables: { value: 3.47 } });

await execute({ schema, document: sampleTopicMutation, variableValues: { value: 3.47 } });
await sleep(0);
expect(subscriptionValue).toEqual(3.47);
});

Expand All @@ -384,15 +432,27 @@ describe("Subscriptions", () => {
}
`;

apolloClient.subscribe({ query: subscriptionQuery }).subscribe({
next: ({ data }) => (subscriptionValue = data!.sampleTopicSubscriptionWithFilter.value),
});
const subscription = (await subscribe({
schema,
document: subscriptionQuery,
})) as AsyncIterableIterator<ExecutionResult>;
// run subscription in a separate async "thread"
(async () => {
for await (const result of subscription) {
subscriptionValue = result.data!.sampleTopicSubscriptionWithFilter.value;
}
})();

await apolloClient.mutate({ mutation, variables: { value: 0.23 } });
await execute({ schema, document: mutation, variableValues: { value: 0.23 } });
await sleep(0);
expect(subscriptionValue).toBeUndefined();
await apolloClient.mutate({ mutation, variables: { value: 0.77 } });

await execute({ schema, document: mutation, variableValues: { value: 0.77 } });
await sleep(0);
expect(subscriptionValue).toEqual(0.77);
await apolloClient.mutate({ mutation, variables: { value: 0.44 } });

await execute({ schema, document: mutation, variableValues: { value: 0.44 } });
await sleep(0);
expect(subscriptionValue).toEqual(0.77);
});

Expand All @@ -416,15 +476,27 @@ describe("Subscriptions", () => {
}
`;

apolloClient.subscribe({ query: subscriptionQuery }).subscribe({
next: ({ data }) => (subscriptionValue = data!.multipleTopicSubscription.value),
});
const subscription = (await subscribe({
schema,
document: subscriptionQuery,
})) as AsyncIterableIterator<ExecutionResult>;
// run subscription in a separate async "thread"
(async () => {
for await (const result of subscription) {
subscriptionValue = result.data!.multipleTopicSubscription.value;
}
})();

await apolloClient.mutate({ mutation: sampleTopicMutation, variables: { value: 0.23 } });
await execute({ schema, document: sampleTopicMutation, variableValues: { value: 0.23 } });
await sleep(0);
expect(subscriptionValue).toEqual(0.23);
await apolloClient.mutate({ mutation: otherTopicMutation, variables: { value: 0.77 } });

await execute({ schema, document: otherTopicMutation, variableValues: { value: 0.77 } });
await sleep(0);
expect(subscriptionValue).toEqual(0.77);
await apolloClient.mutate({ mutation: sampleTopicMutation, variables: { value: 0.44 } });

await execute({ schema, document: sampleTopicMutation, variableValues: { value: 0.44 } });
await sleep(0);
expect(subscriptionValue).toEqual(0.44);
});

Expand All @@ -444,22 +516,46 @@ describe("Subscriptions", () => {
}
`;

apolloClient
.subscribe({
query: dynamicTopicSubscription,
variables: { topic: SAMPLE_TOPIC },
})
.subscribe({
next: ({ data }) => (subscriptionValue = data!.dynamicTopicSubscription.value),
});

await apolloClient.mutate({
await subscribeOnceAndMutate({
subscription: dynamicTopicSubscription,
subscriptionVariables: { topic: SAMPLE_TOPIC },
mutation: pubSubMutationDynamicTopic,
variables: { value: 0.23, topic: SAMPLE_TOPIC },
mutationVariables: { value: 0.23, topic: SAMPLE_TOPIC },
onSubscribedData: data => {
subscriptionValue = data.dynamicTopicSubscription.value;
},
});

expect(subscriptionValue).toEqual(0.23);
});

it("should correctly subscribe with custom subscribe function", async () => {
let subscriptionValue!: number;
const testedValue = Math.PI;
const subscription = gql`
subscription {
customSubscribeSubscription {
value
}
}
`;
const mutation = gql`
mutation {
pubSubMutationCustomSubscription(value: ${testedValue})
}
`;

await subscribeOnceAndMutate({
subscription,
mutation,
onSubscribedData: data => {
subscriptionValue = data.customSubscribeSubscription.value;
},
});

expect(subscriptionValue).toEqual(testedValue);
});

it("should inject the provided custom PubSub implementation", async () => {
let pubSub: any;
getMetadataStorage().clear();
Expand Down Expand Up @@ -572,31 +668,5 @@ describe("Subscriptions", () => {
expect(err.message).not.toContain("class SampleResolver");
}
});

it("should correctly subscribe with custom subscribe function", async () => {
let subscriptionValue!: number;
const testedValue = Math.PI;
const subscriptionQuery = gql`
subscription {
customSubscribeSubscription {
value
}
}
`;
const mutation = gql`
mutation {
pubSubMutationCustomSubscription(value: ${testedValue})
}
`;

apolloClient.subscribe({ query: subscriptionQuery }).subscribe({
next: ({ data }) => {
subscriptionValue = data!.customSubscribeSubscription.value;
},
});
await apolloClient.mutate({ mutation });

expect(subscriptionValue).toEqual(testedValue);
});
});
});
3 changes: 3 additions & 0 deletions tests/helpers/sleep.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
Loading

0 comments on commit 23e9b25

Please sign in to comment.