-
Notifications
You must be signed in to change notification settings - Fork 758
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
Importing Stripe via ES Modules does not respect monkey-patching 'http' #1844
Comments
Hello @janhesters, thank you for writing in.
I don't know a whole lot about the MSW library, but their documentation says
That link took me to https://github.com/mswjs/interceptors#interceptors, and so based on that I made a little test to see if the underlying "ClientRequestInterceptor" is capable of intercepting requests from stripe-node. // server.js
const { ClientRequestInterceptor } = require('@mswjs/interceptors/ClientRequest')
const interceptor = new ClientRequestInterceptor()
interceptor.apply()
interceptor.on('request', ({ request, requestId }) => {
console.log('INTERCEPTED: ', request.method, request.url)
request.respondWith(
new Response(
JSON.stringify({data: [{"foo": "bar"}]}),
)
)
})
const stripe = require("stripe")("sk_test_xyz")
stripe.customers.list().then(lst => {
console.log('RECEIVED', lst)
}); Outputs: $ node server.js
INTERCEPTED: GET https://api.stripe.com/v1/customers
RECEIVED { data: [ { foo: 'bar' } ] } This would seem to absolve |
@richardm-stripe Interesting! Thank you so much for your fast reply, I'll look into it some more. |
@richardm-stripe Interestingly, this seems to be tied to the usage of the Consider the code snippet below: // @vitest-environment node
import { setupServer } from 'msw/node';
import Stripe from 'stripe';
import invariant from 'tiny-invariant';
import { describe, expect, test } from 'vitest';
import {
mockStripePrices,
mockStripeProducts,
} from '~/test/mocks/fixtures/stripe';
import { stripeHandlers } from '~/test/mocks/handlers/stripe';
invariant(
process.env.STRIPE_SECRET_KEY,
'STRIPE_SECRET_KEY environment variable is required',
);
const server = setupServer(...stripeHandlers);
beforeAll(() => server.listen({ onUnhandledRequest: 'warn' }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
describe('with require', () => {
const stripe: Stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
test('it works', async () => {
const products = await stripe.products.list();
const actual = products.data;
const expected = mockStripeProducts;
expect(actual).toEqual(expected);
});
describe('with sequential fetches', () => {
test('it works', async () => {
async function fetchStripeProductsWithPrices() {
const products = await stripe.products.list();
const prices = await stripe.prices.list();
return { products: products.data, prices: prices.data };
}
const actual = await fetchStripeProductsWithPrices();
const expected = {
products: mockStripeProducts,
prices: mockStripePrices,
};
expect(actual).toEqual(expected);
});
});
describe('with parallel fetches', () => {
test.skip('it times out', async () => {
async function fetchStripeProductsWithPrices() {
const [products, prices] = await Promise.all([
stripe.products.list(),
stripe.prices.list(),
]);
return { products: products.data, prices: prices.data };
}
const actual = await fetchStripeProductsWithPrices();
const expected = {
products: mockStripeProducts,
prices: mockStripePrices,
};
expect(actual).toEqual(expected);
});
});
});
describe.skip('with new keyword', () => {
test('it fails', async () => {
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: '2022-11-15',
});
const products = await stripe.products.list();
const actual = products.data;
const expected = mockStripeProducts;
expect(actual).toEqual(expected);
});
}); A few things to note:
We're going to go with the We do suspect either in Stripe or in MSW there is something wrong. And our guess is with the Stripe node SDK, because all other SDK's that we're using (e.g OpenAI, Sendgrid, Twitter, etc.) all work fine no matter how we use them. So we suspect there is something special with the Stripe node SDK in terms of how it sends requests. Even when we wrote manual calls with Axios to the Stripe API, they worked. Thank you again, @richardm-stripe, for your help! 🙏 |
I think I tracked down what's happening here. See mswjs/interceptors#201 MSW won't work if you do import * as https from 'https'; only import https from 'https'; And in stripe-node, we do the former. I'll briefly investigate to confirm switching is feasible. |
I found nock/nock#2461 too. |
@richardm-stripe Wow, thank you for digging! That looks like a promising lead. |
This should be fixed in the next release on Thursday, leaving it open until then. |
@richardm-stripe Thanks a ton! 🙏 |
Turns out #1854 is not viable because I think we can still find a way to make a similar idea work but we won't land it today as expected. |
@richardm-stripe Got it, thank you for the update! |
@anniel-stripe amazing, thank you! |
Describe the bug
When trying to mock responses made with stripe-node in a Node.js enviroment, the requests hit the real server instead of getting caught by MSW.
To Reproduce
You can copy and paste the code below. (Either write actual handlers for your
stripeHandlers
, or you can leave them out, as we did below. If you want to try it out with handlers, simply spread them intosetupServer
.)Sine we configured
onUnhandledRequest: 'warn'
MSW should log out to the console when requests are uncaught. The manual method withaxios
works correctly and logs out this warning / reacts when you configure handlers.However, the second (in the code blocked
skip
ped) test does NOT log out this warning and simply hits the servers.Expected behavior
MSW can intercept the Stripe requests.
I assume this library does HTTP requests somehow esoterically, so it would be nice to learn how it does it, so that we can get MSW to work.
Code snippets
No response
OS
macOS
Node version
18.6.0
Library version
stripe-node v12.12.0
API version
2022-11-15
Additional context
No response
The text was updated successfully, but these errors were encountered: