stripe / stripe-mock

stripe-mock is a mock HTTP server that responds like the real Stripe API. It can be used instead of Stripe's testmode to make test suites integrating with Stripe faster and less brittle.
MIT License
1.37k stars 109 forks source link

`GET /subscriptions/:id` not returning the param ID in the whole response #902

Open krystof-k opened 3 months ago

krystof-k commented 3 months ago

Consider the following request:

curl http://localhost:12111/v1/subscriptions/sub_1MowQVLkdIwHu7ixeRlqHVzs

It returns the ID from URL parameter (sub_1MowQVLkdIwHu7ixeRlqHVzs) only in the id key, but not in other nested keys where it should match:

{
  "id": "sub_1MowQVLkdIwHu7ixeRlqHVzs",
  "items": {
    "data": [
      {
        "subscription": "sub_1OPoulJN5vQBdWExmDmopkQy"
      }
    ],
    "url": "/v1/subscription_items?subscription=sub_1OPouiJN5vQBdWExOgfg6t5C"
  }
}
Full json ```json { "application": null, "application_fee_percent": null, "automatic_tax": { "enabled": false, "liability": null }, "billing_cycle_anchor": 1234567890, "billing_cycle_anchor_config": null, "billing_thresholds": null, "cancel_at": 1234567890, "cancel_at_period_end": false, "canceled_at": 1234567890, "cancellation_details": { "comment": null, "feedback": null, "reason": null }, "collection_method": "charge_automatically", "created": 1234567890, "currency": "usd", "current_period_end": 1234567890, "current_period_start": 1234567890, "customer": "cus_PEHTIoPSgT0tXQ", "days_until_due": null, "default_payment_method": null, "default_source": null, "default_tax_rates": [], "description": null, "discount": null, "discounts": [ { "checkout_session": null, "coupon": { "amount_off": null, "created": 1028554472, "currency": null, "duration": "forever", "duration_in_months": null, "id": "obj_123", "livemode": true, "max_redemptions": null, "metadata": null, "name": null, "object": "coupon", "percent_off": null, "redeem_by": null, "times_redeemed": 990066668, "valid": true }, "customer": null, "end": null, "id": "obj_123", "invoice": null, "invoice_item": null, "object": "discount", "promotion_code": null, "start": 109757538, "subscription": null, "subscription_item": null } ], "ended_at": 1234567890, "id": "sub_1MowQVLkdIwHu7ixeRlqHVzs", "items": { "data": [ { "billing_thresholds": null, "created": 1703175363, "discounts": [ { "checkout_session": null, "coupon": { "amount_off": null, "created": 1028554472, "currency": null, "duration": "forever", "duration_in_months": null, "id": "obj_123", "livemode": true, "max_redemptions": null, "metadata": null, "name": null, "object": "coupon", "percent_off": null, "redeem_by": null, "times_redeemed": 990066668, "valid": true }, "customer": null, "end": null, "id": "obj_123", "invoice": null, "invoice_item": null, "object": "discount", "promotion_code": null, "start": 109757538, "subscription": null, "subscription_item": null } ], "id": "si_PEHTIbRiA7RW9V", "metadata": {}, "object": "subscription_item", "price": { "active": true, "billing_scheme": "per_unit", "created": 1703175360, "currency": "usd", "custom_unit_amount": null, "id": "price_1OPouiJN5vQBdWExAQaqTooZ", "livemode": false, "lookup_key": null, "metadata": {}, "nickname": null, "object": "price", "product": "prod_PEHTfnvdJH6K0k", "recurring": { "aggregate_usage": null, "interval": "month", "interval_count": 1, "usage_type": "licensed" }, "tax_behavior": "unspecified", "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 2000, "unit_amount_decimal": "2000" }, "quantity": 1, "subscription": "sub_1OPoulJN5vQBdWExmDmopkQy", "tax_rates": [] } ], "has_more": false, "object": "list", "url": "/v1/subscription_items?subscription=sub_1OPouiJN5vQBdWExOgfg6t5C" }, "latest_invoice": null, "livemode": false, "metadata": {}, "next_pending_invoice_item_invoice": 1234567890, "object": "subscription", "on_behalf_of": null, "pause_collection": null, "payment_settings": { "payment_method_options": null, "payment_method_types": null, "save_default_payment_method": null }, "pending_invoice_item_interval": null, "pending_setup_intent": null, "pending_update": null, "schedule": null, "start_date": 1234567890, "status": "active", "test_clock": null, "transfer_data": null, "trial_end": 1234567890, "trial_settings": { "end_behavior": { "missing_payment_method": "create_invoice" } }, "trial_start": 1234567890 } ```

I guess it would be the same case across all other endpoints. Is this something that can be fixed?

remi-stripe commented 3 months ago

@krystof-k Thanks for the report! The way stripe-mock does this is quite crude and only focuses on returning the id property properly. It doesn't have any API logic in it so it doesn't know that the url property has the id inside. We could do some string matching and replace but that's unlikely we'll get to a fix in the future. Our goal with stripe-mock is to return well formatted (in terms of JSON) objects and not really mirror what the API is doing.

I'll tag as future though since we might try to fix it at some point.

krystof-k commented 3 months ago

Hi @remi-stripe, thanks – yeah, string match & replace was exactly what I was thinking of as a workaround. At least for the IDs it would really helpful.