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

S3 Presign #62

Open
kochie opened this issue Nov 9, 2021 · 14 comments
Open

S3 Presign #62

kochie opened this issue Nov 9, 2021 · 14 comments
Labels
enhancement New feature or request

Comments

@kochie
Copy link

kochie commented Nov 9, 2021

S3 presign is done using a helper library @aws-sdk/s3-request-presigner this seems like something that would need a helper library or additional documentation to mock properly.

It would be good to see a way to mock presign requests. I'm happy to help with this.

@kochie kochie added the enhancement New feature or request label Nov 9, 2021
@m-radzikowski
Copy link
Owner

I looked at it and I think mocking it is not (easily) possible right now with the lib.

Presign is done by a middleware. getSignedUrl() is creating the middleware and makes the send() call. Middleware intercepts the command, generates signed URL, and returns the result instead of proceeding with actually sending the command to AWS. See: https://github.com/aws/aws-sdk-js-v3/blob/main/packages/s3-request-presigner/src/getSignedUrl.ts

The mocking lib does not mock middlewares, but only client send() command. Mocking middleware can be especially hard in this case, since it's created locally in the getSignedUrl() function.

I think the way to go is to mock the whole getSignedUrl() function.

Feel free to submit a PR for this!

@kochie
Copy link
Author

kochie commented Nov 11, 2021

Yeah so at the moment my strategy has been to mock getSignedUrl() and this works but it's a pretty basic mock. I'll look into it but might take some time. I'll post here if I have any updates.

@arunachalamN
Copy link

Yeah, this functionality would be great.

@ShogunPanda
Copy link

An alternative solution is to mock your URL command to return a {presigned: require('url').parse('http://url')}. At least, it worked for me on PutObject.

@jhecking
Copy link

jhecking commented Jun 1, 2023

The best solution I've found is from the referenced issue:

const presigner = require('@aws-sdk/s3-request-presigner/dist-cjs/getSignedUrl') // eslint-disable-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-assignment

sinon.stub(presigner, 'getSignedUrl').resolves('https://s3.amazonaws.com/path/to/object')

@pagameba
Copy link

pagameba commented Oct 19, 2023

I get an error with this (sinon.stub)

TypeError: Descriptor for property getSignedUrl is non-configurable and non-writable

@Roger13
Copy link

Roger13 commented Jan 2, 2024

This is how I've done using jest:

const presigner = require('@aws-sdk/s3-request-presigner/dist-cjs/getSignedUrl')
jest.spyOn(presigner, 'getSignedUrl').mockResolvedValueOnce(signedUrlMockValue)

Thanks for the simple solution @jhecking 🙌

@major-mayer
Copy link

This is how I've done using jest:

const presigner = require('@aws-sdk/s3-request-presigner/dist-cjs/getSignedUrl')
jest.spyOn(presigner, 'getSignedUrl').mockResolvedValueOnce(signedUrlMockValue)

Thanks for the simple solution @jhecking 🙌

This works great, but you need to expose (fake) AWS credentials, or otherwise it will complain.

CredentialsProviderError: Could not load credentials from any providers

@major-mayer
Copy link

Similar behaviour can be achieved for createPresignedPost from s3-presigned-post.

const postPresigner = require('@aws-sdk/s3-presigned-post/dist-cjs/createPresignedPost.js')
jest.spyOn(postPresigner, 'createPresignedPost').mockResolvedValue({ url: 'mockValue',
	fields: {
		key: 'mockValue',
		Policy: 'mockValue',
		'X-Amz-Signature': 'mockValue',
		'X-Amz-Security-Token': 'mockValue',
		bucket: 'mockValue',
		'X-Amz-Algorithm': 'mockValue',
		'X-Amz-Credential': 'mockValue',
		'X-Amz-Date': 'mockValue',
	} })

@Ribosom
Copy link

Ribosom commented Mar 28, 2024

This is how I've done using jest:

const presigner = require('@aws-sdk/s3-request-presigner/dist-cjs/getSignedUrl')
jest.spyOn(presigner, 'getSignedUrl').mockResolvedValueOnce(signedUrlMockValue)

Thanks for the simple solution @jhecking 🙌

Thank you. I had to change it, but your approach helped me.

My solution:

jest.mock("@aws-sdk/s3-request-presigner", () => {
  return {
    getSignedUrl: jest.fn().mockResolvedValueOnce(signedUrlMockValue),
  };
});

@garysassano
Copy link

This is how I've done using jest:

const presigner = require('@aws-sdk/s3-request-presigner/dist-cjs/getSignedUrl')
jest.spyOn(presigner, 'getSignedUrl').mockResolvedValueOnce(signedUrlMockValue)

Thanks for the simple solution @jhecking 🙌

This solution doesn't work anymore starting from SDK v3.495.0 unfortunately.

@Krrish92
Copy link

Is there any PR open to support getSignedUrl mock ? I am completely blocked as work around discussed above as well not working with new version of sdk

@m-radzikowski
Copy link
Owner

If someone wants to create a PR, I will gladly review it.

@voslartomas
Copy link

For those still struggling with this issue even today, you can workaround it with reimporting getSignedUrl to your own module like described in here https://stackoverflow.com/questions/72616800/trying-to-stub-a-function-results-in-descriptor-for-property-is-non-configurable/72793194#72793194

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

No branches or pull requests