Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit test jest upload issue #238

Closed
alejocg20 opened this issue Mar 13, 2021 · 5 comments
Closed

Unit test jest upload issue #238

alejocg20 opened this issue Mar 13, 2021 · 5 comments

Comments

@alejocg20
Copy link

I am having the following error

{
      errors: [
        GraphQLError [Object]: Variable "$file" got invalid value {}; Upload value invalid.
            at C:\Users\alejo\WebstormProjects\cm-appointments-bed\node_modules\graphql\execution\values.js:116:15
            at coerceInputValueImpl (C:\Users\alejo\WebstormProjects\cm-appointments-bed\node_modules\graphql\utilities\coerceInputValue.js:132:9)
            at coerceInputValueImpl (C:\Users\alejo\WebstormProjects\cm-appointments-bed\node_modules\graphql\utilities\coerceInputValue.js:56:14)
            at coerceInputValue (C:\Users\alejo\WebstormProjects\cm-appointments-bed\node_modules\graphql\utilities\coerceInputValue.js:39:10)
            at _loop (C:\Users\alejo\WebstormProjects\cm-appointments-bed\node_modules\graphql\execution\values.js:109:69)
            at coerceVariableValues (C:\Users\alejo\WebstormProjects\cm-appointments-bed\node_modules\graphql\execution\values.js:121:16)
            at getVariableValues (C:\Users\alejo\WebstormProjects\cm-appointments-bed\node_modules\graphql\execution\values.js:50:19)
            at buildExecutionContext (C:\Users\alejo\WebstormProjects\cm-appointments-bed\node_modules\graphql\execution\execute.js:190:61)
            at executeImpl (C:\Users\alejo\WebstormProjects\cm-appointments-bed\node_modules\graphql\execution\execute.js:87:20)
            at execute (C:\Users\alejo\WebstormProjects\cm-appointments-bed\node_modules\graphql\execution\execute.js:62:35)
            at graphqlImpl (C:\Users\alejo\WebstormProjects\cm-appointments-bed\node_modules\graphql\graphql.js:108:31)
            at C:\Users\alejo\WebstormProjects\cm-appointments-bed\node_modules\graphql\graphql.js:28:31
            at new Promise (<anonymous>)
            at Object.graphql (C:\Users\alejo\WebstormProjects\cm-appointments-bed\node_modules\graphql\graphql.js:26:10)
            at Object.exports.graphqlTestCall (C:\Users\alejo\WebstormProjects\cm-appointments-bed\src\utils\test\graphqlTestCall.ts:30:10)
            at processTicksAndRejections (internal/process/task_queues.js:93:5)
            at Object.<anonymous> (C:\Users\alejo\WebstormProjects\cm-appointments-bed\src\test\user.spec.ts:498:24) {
          locations: [Array]
        }
      ]
    }

Right now is only failing in the unit test, with the productive app it is working the uploading file functionality. I had the same error message with the productive app and I solved it adding the following to the package.json

 "resolutions": {
    "graphql-upload": "^11.0.0"
  },

I will share with you the unit test code

    test('Add profile picture', async () => {
      const fileName = 'logo.png';
      const file = fs.createReadStream(
        path.resolve(__dirname, `../utils/test/factory/${fileName}`)
      );
      const fileStream = new Promise((resolve) =>
        resolve({
          createReadStream: () => file,
          stream: file,
          filename: fileName,
          mimetype: 'application/png',
        })
      );
      const { id } = await createCoach({
        ...userData,
        userType: UserType.US,
      });
      await createRefreshToken({
        ...userData,
        valid: true,
        id,
      });
      const response = await graphqlTestCall({
        source: addProfilePictureMutation,
        variableValues: {
          id: { id },
          file: fileStream,
        },
      });
      console.log(response);
      expect(response.data.addProfilePicture).toEqual({
        id,
        profilePicture: true,
      });
      expect(sharp.mock.calls.length).toBe(resolutions.length);
    });

In addition this is the graphqlTestCall code

import { graphql, GraphQLSchema } from 'graphql';
import { buildSchema, Maybe } from 'type-graphql';
import { allResolvers } from '../../resolvers';
import { customAuthChecker } from '../../middleware/auth';
import { mockShortToken } from './shortToken';

interface Options {
  source: string;
  variableValues?: Maybe<{
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    [key: string]: any;
  }>;
  shortToken?: string;
}

let schema: GraphQLSchema;

export const graphqlTestCall = async ({
  source,
  variableValues,
  shortToken = mockShortToken(),
}: Options) => {
  if (!schema) {
    schema = await buildSchema({
      resolvers: allResolvers,
      validate: true,
      authChecker: customAuthChecker,
    });
  }
  return graphql({
    schema,
    source,
    contextValue: {
      ...(shortToken && {
        req: {
          headers: {
            authorization: `Bearer ${shortToken}`,
          },
        },
      }),
    },
    variableValues,
  });
};

@elisalimli
Copy link

You should send file,that's why it's throw that error.You just have filename

@jaydenseric
Copy link
Owner

Your problem is because the Upload Scalar is expecting the value coming in to be an Upload instance:

https://github.com/jaydenseric/graphql-upload#class-upload

Maybe you could update your approach to use that class, but I've personally never considered testing resolvers like that. I've only ever made full GraphQL multipart requests in tests.

Closing because this is more of a request for help with your project using Jest and apparently Apollo Server; whereas this issue tracker is for raising specific and reproducible graphql-upload bugs. Feel free to share your solution here though, whatever it ends up being :)

@alejocg20
Copy link
Author

alejocg20 commented Mar 16, 2021

You should send file,that's why it's throw that error.You just have filename

Hi @alisalim17 thanks for your reply. But I didnt understand, what do you mean ?? Could you be a little be more explicit, because I am sending the FileStream promise.

Thanks

@jaimepater
Copy link

I had the same issue, I resolved changing

      const fileStream = new Promise((resolve) =>
        resolve({
          createReadStream: () => file,
          stream: file,
          filename: fileName,
          mimetype: 'application/png',
        })
      );

for

  const upload = new Upload();
      upload.resolve({
        createReadStream: () => file,
        stream: file,
        filename: fileName,
        encoding: '7bit',
        mimetype: 'application/png',
      });
      

@alejocg20
Copy link
Author

I had the same issue, I resolved changing

      const fileStream = new Promise((resolve) =>
        resolve({
          createReadStream: () => file,
          stream: file,
          filename: fileName,
          mimetype: 'application/png',
        })
      );

for

  const upload = new Upload();
      upload.resolve({
        createReadStream: () => file,
        stream: file,
        filename: fileName,
        encoding: '7bit',
        mimetype: 'application/png',
      });
      

Thanks @jaimepater worked

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants