saas-subscription-helper
Version:
A helper package for integrating Stripe Payment Links with Supabase in SaaS applications.
104 lines (93 loc) • 3.68 kB
JavaScript
const { mockSupabase, mockStripe } = require('../setup');
const { handleWebhooks } = require('../../src/stripe');
const supabaseModule = require('../../src/supabase');
// Mock the entire module
jest.mock('../../src/supabase', () => ({
updateUser: jest.fn().mockImplementation(async (config, email, data) => {
console.log('\n[MOCK] updateUser called:', {
config: {
subscriptionField: config.subscriptionField
},
email,
data: JSON.stringify(data, null, 2)
});
return {
data: [{ ...data }],
error: null
};
})
}));
describe('handleWebhooks', () => {
const config = {
stripeSecretKey: 'test_key',
supabaseUrl: 'https://test.supabase.co',
supabaseKey: 'test_key',
table: 'users',
emailField: 'email',
subscriptionField: 'subscription_status',
debug: true,
stripeWebhookSecret: 'whsec_test'
};
beforeEach(() => {
jest.clearAllMocks();
// Verify mock is clean
console.log('Mock state after clear:', {
calls: supabaseModule.updateUser.mock.calls.length
});
});
it('handles subscription.deleted event', async () => {
console.log('\n=== Starting subscription.deleted test ===');
console.log('Initial capturedData:', supabaseModule.updateUser.mockImplementation.capturedData);
const event = {
type: 'customer.subscription.deleted',
data: {
object: {
id: 'sub_123',
customer: 'cus_123',
status: 'canceled',
items: {
data: [{
price: { id: 'price_premium' }
}]
}
}
}
};
console.log('Event data:', JSON.stringify(event, null, 2));
const rawBody = JSON.stringify(event);
const headers = {
'stripe-signature': 'test_signature'
};
mockStripe.webhooks.constructEvent.mockImplementationOnce(() => event);
mockStripe.customers.retrieve.mockResolvedValueOnce({
email: 'test@example.com'
});
console.log('\n[TEST] BEFORE handleWebhooks call');
await handleWebhooks(config, rawBody, headers);
console.log('\n[TEST] AFTER handleWebhooks call');
console.log('[TEST] updateUser mock state:', {
calls: supabaseModule.updateUser.mock.calls.length,
results: supabaseModule.updateUser.mock.results.map(r => r.value),
lastCallArgs: supabaseModule.updateUser.mock.calls[supabaseModule.updateUser.mock.calls.length - 1]
});
console.log('Final data comparison:');
const lastCallData = supabaseModule.updateUser.mock.calls[0]?.[2];
console.log('Captured:', JSON.stringify(lastCallData, null, 2));
expect(lastCallData).toEqual({
[config.subscriptionField]: 'inactive',
stripe_price_id: null
});
// Verify the mock was called
expect(supabaseModule.updateUser).toHaveBeenCalled();
console.log('Mock calls:', supabaseModule.updateUser.mock.calls.map(call => ({
email: call[1],
data: call[2]
})));
// Then check the data
const lastCall = supabaseModule.updateUser.mock.calls[supabaseModule.updateUser.mock.calls.length - 1];
expect(lastCall[2]).toEqual({
[config.subscriptionField]: 'inactive',
stripe_price_id: null
});
});
});