import gql from 'graphql-tag';
import 'jest';
import { createTestClient } from 'apollo-server-testing';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloServer } from 'apollo-server';
import { ApolloClient } from 'apollo-client';
import { typeDefs, resolver } from '@files-stack/graphql-schema';


/**
 * Server side graphql test uses createTestClient from 
 * https://github.com/apollographql/apollo-server/blob/master/packages/apollo-server-testing/src/createTestClient.ts
 */
describe('createTestServer', () => {

    const rootSchema = `
    type Query {
      dummy: Int
    }
    type Mutation {
      dummy: Int
    }
    type Subscription {
        dummy: Int
    }
    `;
    const schemaTypeDef = rootSchema.concat(typeDefs);



    const resolvers = {
        Query: {
            test: (_, { echo }) => echo,
            hello: (_, __, { person }) => {
                return `hello ${person}`;
            },
        },
        Mutation: {
            increment: (_, args) => {
                const a = args.a ? args.a : 0;
                return a + 1;
            },
        },
    };

    const myTestServer = new ApolloServer({
        typeDefs,
        resolvers,
        mockEntireSchema: false,
        context: () => ({ person: 'tom' }),

    });

    it('allows queries', async () => {
        const query = `{ test(echo: "foo") }`;
        const client = createTestClient(myTestServer);
        const res = await client.query({ query });
        expect(res.data).toEqual({ test: 'foo' });
    });

    it('allows mutations', async () => {
        const mutation = `mutation increment { increment }`;
        const client = createTestClient(myTestServer);
        const res = await client.mutate({ mutation });
        expect(res.data).toEqual({ increment: 1 });
    });

    it('allows variables to be passed query', async () => {
        const query = `query test($echo: String){ test(echo: $echo) }`;
        const client = createTestClient(myTestServer);
        const res = await client.query({ query, variables: { echo: 'wow' } } as any);
        expect(res.data).toEqual({ test: 'wow' });
    });

    it('allows variables to be passed to mutation', async () => {
        const mutation = `mutation increment($a: Int) { increment(a: $a) }`;
        const client = createTestClient(myTestServer);
        const res = await client.mutate({ mutation, variables: { a: 2 } } as any);
        expect(res.data).toEqual({ increment: 3 });
    });

    it('resolves with context', async () => {
        const query = `{ hello }`;
        const client = createTestClient(myTestServer);
        const res = await client.query({ query });
        expect(res.data).toEqual({ hello: 'hello tom' });
    });

    it('allows query documents as input', async () => {
        const query = gql`
          {
            test(echo: "foo")
          }
        `;
        const client = createTestClient(myTestServer);
        const clientRes = await client.query({ query });
        expect(clientRes.data).toEqual({ test: 'foo' });

        const mutation = gql`
          mutation increment {
            increment
          }
        `;
        const mutationRes = await client.mutate({ mutation });
        expect(mutationRes.data).toEqual({ increment: 1 });
    });
});
