Skip to content

Instantly share code, notes, and snippets.

@sockol
Last active December 13, 2021 20:34
Show Gist options
  • Save sockol/75fa00c7f0518491bec1565389125891 to your computer and use it in GitHub Desktop.
Save sockol/75fa00c7f0518491bec1565389125891 to your computer and use it in GitHub Desktop.
Unit test file uploads in your Apollo GraphQL Server
const apolloTesting = require(`apollo-server-testing`)
const {
ApolloServer
} = require(`apollo-server-express`)
// see docs at: https://www.apollographql.com/docs/apollo-server/getting-started/
const serverConfig = {
/*
typeDefs,
resolvers,
context,
*/
}
const testServer = new ApolloServer({
...serverConfig,
})
const client = apolloTesting.createTestClient(testServer)
it(`addFile`, async function() {
try {
const filename = `some-powerpoint.pptx`
const file = fs.createReadStream(resolve(`./tests/${filename}`))
const QUERY = `
mutation addFile($file: Upload!) {
addFile(file: $file) {
id
}
}
`
const d = await client.mutate({
query: QUERY,
variables: {
file: new Promise(resolve => resolve({
createReadStream: () => file,
stream: file,
filename: filename,
mimetype: `application/vnd.openxmlformats-officedocument.presentationml.presentation`,
})),
},
})
if (d.errors)
throw new Error(d.errors)
assert(d.data.addFile)
} catch (error) {
throw new Error(error)
}
})
@ottoo
Copy link

ottoo commented Jul 27, 2021

For anyone coming here from google, here is a full complete example using nodeJS 16, Apollo Server 2.25, and graphql-upload 12.

const { ApolloServer, gql } = require("apollo-server-express");
const { Readable } = require("stream");
const { Upload } = require("graphql-upload/public");
const { GraphQLUpload } = require("graphql-upload");

const server = new ApolloServer({
  typeDefs: `
     scalar Upload
     type SomeFile {
       filename: String
       mimetype: String
       content: String
     }
     type Mutation {
       uploadFile(input: Upload): SomeFile!
     }
     type Query {
       dummy: String!
     }
   `,
  resolvers: {
    Upload: GraphQLUpload,
    Mutation: {
      uploadFile: async (_, { input }) => {
        const { createReadStream, filename, mimetype } = await input;
        const chunks = [];
        const stream = createReadStream();
        for await (const chunk of stream) {
          chunks.push(chunk);
        }
        const buf = Buffer.concat(chunks);

        return {
          filename,
          mimetype,
          content: buf.toString(),
        };
      },
    },
    Query: {
      dummy: () => "hi",
    },
  },
  uploads: false,
});

test("mutation", async () => {
  const THE_MUTATION = gql`
    mutation uploadFile($input: Upload!) {
      uploadFile(input: $input) {
        filename
        mimetype
        content
      }
    }
  `;

  const file = Readable.from(Buffer.from("hello upload", "utf-8"));
  const upload = new Upload();
  upload.promise = new Promise((resolve) =>
    resolve({
      createReadStream: () => file,
      filename: "some_file.txt",
      mimetype: "text/plain",
    })
  );

  const result = await server.executeOperation({
    query: THE_MUTATION,
    variables: {
      input: upload,
    },
  });
  expect(result.errors).toBeUndefined();
  expect(result.data).toMatchObject({
    uploadFile: {
      filename: "some_file.txt",
      mimetype: "text/plain",
      content: "hello upload",
    },
  });
});

Save file as mutation.test.js, install dependencies npm i apollo-server-express graphql graphql-upload and run npx jest mutation.test.js.

Thanks for this, helped me a lot with figuring out things after upgrading packages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment