paddle-python-sdk 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (517) hide show
  1. examples/__init__.py +0 -0
  2. examples/catalog_management.py +166 -0
  3. examples/event_polling.py +56 -0
  4. examples/get_products.py +46 -0
  5. examples/logger.py +31 -0
  6. paddle_billing/Client.py +201 -0
  7. paddle_billing/ConditionallyRemoveImportMeta.py +14 -0
  8. paddle_billing/Entities/Address.py +44 -0
  9. paddle_billing/Entities/Adjustment.py +45 -0
  10. paddle_billing/Entities/Adjustments/AdjustmentCustomerBalance.py +18 -0
  11. paddle_billing/Entities/Adjustments/AdjustmentItem.py +26 -0
  12. paddle_billing/Entities/Adjustments/__init__.py +2 -0
  13. paddle_billing/Entities/Business.py +38 -0
  14. paddle_billing/Entities/Collections/AddressCollection.py +18 -0
  15. paddle_billing/Entities/Collections/AdjustmentCollection.py +18 -0
  16. paddle_billing/Entities/Collections/BusinessCollection.py +18 -0
  17. paddle_billing/Entities/Collections/Collection.py +47 -0
  18. paddle_billing/Entities/Collections/CreditBalanceCollection.py +18 -0
  19. paddle_billing/Entities/Collections/CustomerCollection.py +18 -0
  20. paddle_billing/Entities/Collections/DiscountCollection.py +18 -0
  21. paddle_billing/Entities/Collections/EventCollection.py +18 -0
  22. paddle_billing/Entities/Collections/EventTypeCollection.py +18 -0
  23. paddle_billing/Entities/Collections/NotificationCollection.py +18 -0
  24. paddle_billing/Entities/Collections/NotificationLogCollection.py +18 -0
  25. paddle_billing/Entities/Collections/NotificationSettingCollection.py +18 -0
  26. paddle_billing/Entities/Collections/Paginator.py +29 -0
  27. paddle_billing/Entities/Collections/PriceCollection.py +18 -0
  28. paddle_billing/Entities/Collections/ProductCollection.py +18 -0
  29. paddle_billing/Entities/Collections/ReportCollection.py +18 -0
  30. paddle_billing/Entities/Collections/SubscriptionCollection.py +18 -0
  31. paddle_billing/Entities/Collections/SubscriptionPreviewCollection.py +18 -0
  32. paddle_billing/Entities/Collections/TransactionCollection.py +18 -0
  33. paddle_billing/Entities/Collections/TransactionPreviewCollection.py +18 -0
  34. paddle_billing/Entities/Collections/TransactionsDataCollection.py +18 -0
  35. paddle_billing/Entities/Collections/__init__.py +21 -0
  36. paddle_billing/Entities/CreditBalance.py +22 -0
  37. paddle_billing/Entities/Customer.py +36 -0
  38. paddle_billing/Entities/DateTime.py +43 -0
  39. paddle_billing/Entities/Discount.py +51 -0
  40. paddle_billing/Entities/Discounts/DiscountStatus.py +8 -0
  41. paddle_billing/Entities/Discounts/DiscountType.py +7 -0
  42. paddle_billing/Entities/Discounts/__init__.py +2 -0
  43. paddle_billing/Entities/Entity.py +12 -0
  44. paddle_billing/Entities/Event.py +51 -0
  45. paddle_billing/Entities/EventType.py +23 -0
  46. paddle_billing/Entities/Events/EventTypeName.py +52 -0
  47. paddle_billing/Entities/Events/__init__.py +1 -0
  48. paddle_billing/Entities/Notification.py +42 -0
  49. paddle_billing/Entities/NotificationLog.py +25 -0
  50. paddle_billing/Entities/NotificationSetting.py +34 -0
  51. paddle_billing/Entities/NotificationSettings/NotificationSettingType.py +6 -0
  52. paddle_billing/Entities/NotificationSettings/__init__.py +1 -0
  53. paddle_billing/Entities/Notifications/NotificationOrigin.py +6 -0
  54. paddle_billing/Entities/Notifications/NotificationPayout.py +24 -0
  55. paddle_billing/Entities/Notifications/NotificationPayoutStatus.py +6 -0
  56. paddle_billing/Entities/Notifications/NotificationStatus.py +8 -0
  57. paddle_billing/Entities/Notifications/__init__.py +4 -0
  58. paddle_billing/Entities/Price.py +68 -0
  59. paddle_billing/Entities/PricePreview.py +34 -0
  60. paddle_billing/Entities/PricingPreviews/PricePreviewDetails.py +15 -0
  61. paddle_billing/Entities/PricingPreviews/PricePreviewDiscounts.py +20 -0
  62. paddle_billing/Entities/PricingPreviews/PricePreviewItem.py +16 -0
  63. paddle_billing/Entities/PricingPreviews/PricePreviewLineItem.py +38 -0
  64. paddle_billing/Entities/PricingPreviews/PricePreviewTotalsFormatted.py +20 -0
  65. paddle_billing/Entities/PricingPreviews/PricePreviewUnitTotalsFormatted.py +20 -0
  66. paddle_billing/Entities/PricingPreviews/__init__.py +6 -0
  67. paddle_billing/Entities/Product.py +45 -0
  68. paddle_billing/Entities/Report.py +32 -0
  69. paddle_billing/Entities/ReportCSV.py +13 -0
  70. paddle_billing/Entities/Reports/ReportFilter.py +20 -0
  71. paddle_billing/Entities/Reports/ReportFilterName.py +17 -0
  72. paddle_billing/Entities/Reports/ReportFilterOperator.py +6 -0
  73. paddle_billing/Entities/Reports/ReportStatus.py +8 -0
  74. paddle_billing/Entities/Reports/ReportType.py +10 -0
  75. paddle_billing/Entities/Reports/__init__.py +5 -0
  76. paddle_billing/Entities/Shared/Action.py +10 -0
  77. paddle_billing/Entities/Shared/AddressPreview.py +18 -0
  78. paddle_billing/Entities/Shared/AdjustmentItemTotals.py +18 -0
  79. paddle_billing/Entities/Shared/AdjustmentProration.py +18 -0
  80. paddle_billing/Entities/Shared/AdjustmentStatus.py +8 -0
  81. paddle_billing/Entities/Shared/AdjustmentTimePeriod.py +17 -0
  82. paddle_billing/Entities/Shared/AdjustmentTotals.py +26 -0
  83. paddle_billing/Entities/Shared/AdjustmentType.py +8 -0
  84. paddle_billing/Entities/Shared/AvailablePaymentMethods.py +11 -0
  85. paddle_billing/Entities/Shared/BillingDetails.py +22 -0
  86. paddle_billing/Entities/Shared/BillingDetailsUpdate.py +22 -0
  87. paddle_billing/Entities/Shared/Card.py +24 -0
  88. paddle_billing/Entities/Shared/CatalogType.py +6 -0
  89. paddle_billing/Entities/Shared/ChargebackFee.py +18 -0
  90. paddle_billing/Entities/Shared/Checkout.py +12 -0
  91. paddle_billing/Entities/Shared/CollectionMode.py +6 -0
  92. paddle_billing/Entities/Shared/Contacts.py +16 -0
  93. paddle_billing/Entities/Shared/CountryCode.py +233 -0
  94. paddle_billing/Entities/Shared/CurrencyCode.py +34 -0
  95. paddle_billing/Entities/Shared/CurrencyCodeAdjustments.py +7 -0
  96. paddle_billing/Entities/Shared/CurrencyCodePayouts.py +17 -0
  97. paddle_billing/Entities/Shared/CustomData.py +10 -0
  98. paddle_billing/Entities/Shared/Data.py +9 -0
  99. paddle_billing/Entities/Shared/ErrorCode.py +21 -0
  100. paddle_billing/Entities/Shared/ImportMeta.py +16 -0
  101. paddle_billing/Entities/Shared/Interval.py +8 -0
  102. paddle_billing/Entities/Shared/Meta.py +7 -0
  103. paddle_billing/Entities/Shared/MetaPaginated.py +18 -0
  104. paddle_billing/Entities/Shared/MethodDetails.py +19 -0
  105. paddle_billing/Entities/Shared/Money.py +28 -0
  106. paddle_billing/Entities/Shared/Original.py +18 -0
  107. paddle_billing/Entities/Shared/Pagination.py +20 -0
  108. paddle_billing/Entities/Shared/PaymentAttemptStatus.py +13 -0
  109. paddle_billing/Entities/Shared/PaymentMethodType.py +14 -0
  110. paddle_billing/Entities/Shared/PayoutTotalsAdjustment.py +29 -0
  111. paddle_billing/Entities/Shared/PriceQuantity.py +16 -0
  112. paddle_billing/Entities/Shared/Status.py +6 -0
  113. paddle_billing/Entities/Shared/TaxCategory.py +13 -0
  114. paddle_billing/Entities/Shared/TaxMode.py +7 -0
  115. paddle_billing/Entities/Shared/TaxRatesUsed.py +18 -0
  116. paddle_billing/Entities/Shared/TimePeriod.py +18 -0
  117. paddle_billing/Entities/Shared/Totals.py +20 -0
  118. paddle_billing/Entities/Shared/TransactionDetailsPreview.py +22 -0
  119. paddle_billing/Entities/Shared/TransactionLineItemPreview.py +28 -0
  120. paddle_billing/Entities/Shared/TransactionOrigin.py +10 -0
  121. paddle_billing/Entities/Shared/TransactionPaymentAttempt.py +35 -0
  122. paddle_billing/Entities/Shared/TransactionPayoutTotals.py +36 -0
  123. paddle_billing/Entities/Shared/TransactionPayoutTotalsAdjusted.py +29 -0
  124. paddle_billing/Entities/Shared/TransactionStatus.py +11 -0
  125. paddle_billing/Entities/Shared/TransactionTotals.py +36 -0
  126. paddle_billing/Entities/Shared/TransactionTotalsAdjusted.py +28 -0
  127. paddle_billing/Entities/Shared/UnitPriceOverride.py +19 -0
  128. paddle_billing/Entities/Shared/UnitTotals.py +20 -0
  129. paddle_billing/Entities/Shared/__init__.py +56 -0
  130. paddle_billing/Entities/Subscription.py +86 -0
  131. paddle_billing/Entities/SubscriptionPreview.py +79 -0
  132. paddle_billing/Entities/Subscriptions/SubscriptionAdjustmentItem.py +24 -0
  133. paddle_billing/Entities/Subscriptions/SubscriptionAdjustmentPreview.py +22 -0
  134. paddle_billing/Entities/Subscriptions/SubscriptionCharge.py +18 -0
  135. paddle_billing/Entities/Subscriptions/SubscriptionCredit.py +18 -0
  136. paddle_billing/Entities/Subscriptions/SubscriptionDetails.py +34 -0
  137. paddle_billing/Entities/Subscriptions/SubscriptionDiscount.py +19 -0
  138. paddle_billing/Entities/Subscriptions/SubscriptionEffectiveFrom.py +6 -0
  139. paddle_billing/Entities/Subscriptions/SubscriptionItem.py +35 -0
  140. paddle_billing/Entities/Subscriptions/SubscriptionItemStatus.py +7 -0
  141. paddle_billing/Entities/Subscriptions/SubscriptionItems.py +20 -0
  142. paddle_billing/Entities/Subscriptions/SubscriptionItemsWithPrice.py +19 -0
  143. paddle_billing/Entities/Subscriptions/SubscriptionManagementUrls.py +16 -0
  144. paddle_billing/Entities/Subscriptions/SubscriptionNextTransaction.py +23 -0
  145. paddle_billing/Entities/Subscriptions/SubscriptionNonCatalogPrice.py +30 -0
  146. paddle_billing/Entities/Subscriptions/SubscriptionNonCatalogPriceWithProduct.py +32 -0
  147. paddle_billing/Entities/Subscriptions/SubscriptionNonCatalogProduct.py +26 -0
  148. paddle_billing/Entities/Subscriptions/SubscriptionOnPaymentFailure.py +6 -0
  149. paddle_billing/Entities/Subscriptions/SubscriptionPreviewSubscriptionUpdateSummary.py +22 -0
  150. paddle_billing/Entities/Subscriptions/SubscriptionPrice.py +28 -0
  151. paddle_billing/Entities/Subscriptions/SubscriptionProration.py +18 -0
  152. paddle_billing/Entities/Subscriptions/SubscriptionProrationBillingMode.py +9 -0
  153. paddle_billing/Entities/Subscriptions/SubscriptionResult.py +22 -0
  154. paddle_billing/Entities/Subscriptions/SubscriptionResultAction.py +6 -0
  155. paddle_billing/Entities/Subscriptions/SubscriptionResumeEffectiveFrom.py +5 -0
  156. paddle_billing/Entities/Subscriptions/SubscriptionScheduledChange.py +21 -0
  157. paddle_billing/Entities/Subscriptions/SubscriptionScheduledChangeAction.py +7 -0
  158. paddle_billing/Entities/Subscriptions/SubscriptionStatus.py +10 -0
  159. paddle_billing/Entities/Subscriptions/SubscriptionTimePeriod.py +17 -0
  160. paddle_billing/Entities/Subscriptions/SubscriptionTransactionItem.py +23 -0
  161. paddle_billing/Entities/Subscriptions/SubscriptionTransactionLineItem.py +33 -0
  162. paddle_billing/Entities/Subscriptions/SubscriptionUpdateItem.py +16 -0
  163. paddle_billing/Entities/Subscriptions/__init__.py +31 -0
  164. paddle_billing/Entities/Transaction.py +98 -0
  165. paddle_billing/Entities/TransactionData.py +15 -0
  166. paddle_billing/Entities/TransactionPreview.py +40 -0
  167. paddle_billing/Entities/Transactions/TransactionAdjustmentsTotals.py +30 -0
  168. paddle_billing/Entities/Transactions/TransactionBreakdown.py +18 -0
  169. paddle_billing/Entities/Transactions/TransactionCardType.py +14 -0
  170. paddle_billing/Entities/Transactions/TransactionCreateItem.py +16 -0
  171. paddle_billing/Entities/Transactions/TransactionCreateItemWithPrice.py +11 -0
  172. paddle_billing/Entities/Transactions/TransactionDetails.py +32 -0
  173. paddle_billing/Entities/Transactions/TransactionItem.py +24 -0
  174. paddle_billing/Entities/Transactions/TransactionItemPreviewWithNonCatalogPrice.py +21 -0
  175. paddle_billing/Entities/Transactions/TransactionItemPreviewWithPrice.py +24 -0
  176. paddle_billing/Entities/Transactions/TransactionItemPreviewWithPriceId.py +18 -0
  177. paddle_billing/Entities/Transactions/TransactionLineItem.py +35 -0
  178. paddle_billing/Entities/Transactions/TransactionNonCatalogPrice.py +39 -0
  179. paddle_billing/Entities/Transactions/TransactionNonCatalogPriceWithProduct.py +41 -0
  180. paddle_billing/Entities/Transactions/TransactionNonCatalogProduct.py +25 -0
  181. paddle_billing/Entities/Transactions/TransactionProration.py +18 -0
  182. paddle_billing/Entities/Transactions/TransactionTimePeriod.py +17 -0
  183. paddle_billing/Entities/Transactions/TransactionUpdateTransactionItem.py +8 -0
  184. paddle_billing/Entities/Transactions/__init__.py +20 -0
  185. paddle_billing/Entities/__init__.py +0 -0
  186. paddle_billing/EnumStringify.py +2 -0
  187. paddle_billing/Environment.py +14 -0
  188. paddle_billing/Exceptions/ApiError.py +28 -0
  189. paddle_billing/Exceptions/ApiErrors/AddressApiError.py +5 -0
  190. paddle_billing/Exceptions/ApiErrors/AdjustmentApiError.py +5 -0
  191. paddle_billing/Exceptions/ApiErrors/BusinessApiError.py +5 -0
  192. paddle_billing/Exceptions/ApiErrors/CustomerApiError.py +5 -0
  193. paddle_billing/Exceptions/ApiErrors/DiscountApiError.py +5 -0
  194. paddle_billing/Exceptions/ApiErrors/PriceApiError.py +5 -0
  195. paddle_billing/Exceptions/ApiErrors/ProductApiError.py +5 -0
  196. paddle_billing/Exceptions/ApiErrors/SubscriptionApiError.py +5 -0
  197. paddle_billing/Exceptions/ApiErrors/TransactionApiError.py +5 -0
  198. paddle_billing/Exceptions/ApiErrors/__init__.py +0 -0
  199. paddle_billing/Exceptions/FieldError.py +8 -0
  200. paddle_billing/Exceptions/SdkException.py +2 -0
  201. paddle_billing/Exceptions/SdkExceptions/InvalidArgumentException.py +8 -0
  202. paddle_billing/Exceptions/SdkExceptions/MalformedResponse.py +7 -0
  203. paddle_billing/Exceptions/SdkExceptions/__init__.py +0 -0
  204. paddle_billing/Exceptions/__init__.py +0 -0
  205. paddle_billing/FiltersNone.py +8 -0
  206. paddle_billing/FiltersUndefined.py +11 -0
  207. paddle_billing/HasParameters.py +11 -0
  208. paddle_billing/Logger/Formatter.py +18 -0
  209. paddle_billing/Logger/NullHandler.py +6 -0
  210. paddle_billing/Logger/__init__.py +30 -0
  211. paddle_billing/Notifications/Entities/Address.py +44 -0
  212. paddle_billing/Notifications/Entities/Adjustment.py +45 -0
  213. paddle_billing/Notifications/Entities/Adjustments/AdjustmentItem.py +26 -0
  214. paddle_billing/Notifications/Entities/Adjustments/__init__.py +1 -0
  215. paddle_billing/Notifications/Entities/Business.py +39 -0
  216. paddle_billing/Notifications/Entities/Businesses/BusinessesContacts.py +16 -0
  217. paddle_billing/Notifications/Entities/Businesses/__init__.py +1 -0
  218. paddle_billing/Notifications/Entities/Customer.py +36 -0
  219. paddle_billing/Notifications/Entities/DateTime.py +43 -0
  220. paddle_billing/Notifications/Entities/Discount.py +51 -0
  221. paddle_billing/Notifications/Entities/Discounts/DiscountStatus.py +8 -0
  222. paddle_billing/Notifications/Entities/Discounts/DiscountType.py +7 -0
  223. paddle_billing/Notifications/Entities/Discounts/__init__.py +2 -0
  224. paddle_billing/Notifications/Entities/Entity.py +12 -0
  225. paddle_billing/Notifications/Entities/Payout.py +24 -0
  226. paddle_billing/Notifications/Entities/Payouts/PayoutStatus.py +6 -0
  227. paddle_billing/Notifications/Entities/Payouts/__init__.py +1 -0
  228. paddle_billing/Notifications/Entities/Price.py +66 -0
  229. paddle_billing/Notifications/Entities/Product.py +45 -0
  230. paddle_billing/Notifications/Entities/Report.py +32 -0
  231. paddle_billing/Notifications/Entities/Reports/ReportFilter.py +20 -0
  232. paddle_billing/Notifications/Entities/Reports/ReportFilterName.py +17 -0
  233. paddle_billing/Notifications/Entities/Reports/ReportFilterOperator.py +6 -0
  234. paddle_billing/Notifications/Entities/Reports/ReportStatus.py +8 -0
  235. paddle_billing/Notifications/Entities/Reports/ReportType.py +10 -0
  236. paddle_billing/Notifications/Entities/Reports/__init__.py +5 -0
  237. paddle_billing/Notifications/Entities/Shared/Action.py +10 -0
  238. paddle_billing/Notifications/Entities/Shared/AddressPreview.py +18 -0
  239. paddle_billing/Notifications/Entities/Shared/AdjustmentItemTotals.py +18 -0
  240. paddle_billing/Notifications/Entities/Shared/AdjustmentProration.py +18 -0
  241. paddle_billing/Notifications/Entities/Shared/AdjustmentStatus.py +8 -0
  242. paddle_billing/Notifications/Entities/Shared/AdjustmentTimePeriod.py +17 -0
  243. paddle_billing/Notifications/Entities/Shared/AdjustmentTotals.py +26 -0
  244. paddle_billing/Notifications/Entities/Shared/AdjustmentType.py +8 -0
  245. paddle_billing/Notifications/Entities/Shared/AvailablePaymentMethods.py +11 -0
  246. paddle_billing/Notifications/Entities/Shared/BillingDetails.py +22 -0
  247. paddle_billing/Notifications/Entities/Shared/Card.py +24 -0
  248. paddle_billing/Notifications/Entities/Shared/CatalogType.py +6 -0
  249. paddle_billing/Notifications/Entities/Shared/ChargebackFee.py +18 -0
  250. paddle_billing/Notifications/Entities/Shared/Checkout.py +12 -0
  251. paddle_billing/Notifications/Entities/Shared/CollectionMode.py +6 -0
  252. paddle_billing/Notifications/Entities/Shared/CountryCode.py +233 -0
  253. paddle_billing/Notifications/Entities/Shared/CurrencyCode.py +34 -0
  254. paddle_billing/Notifications/Entities/Shared/CurrencyCodeAdjustments.py +7 -0
  255. paddle_billing/Notifications/Entities/Shared/CurrencyCodePayouts.py +17 -0
  256. paddle_billing/Notifications/Entities/Shared/CustomData.py +10 -0
  257. paddle_billing/Notifications/Entities/Shared/Data.py +9 -0
  258. paddle_billing/Notifications/Entities/Shared/ErrorCode.py +21 -0
  259. paddle_billing/Notifications/Entities/Shared/ImportMeta.py +16 -0
  260. paddle_billing/Notifications/Entities/Shared/Interval.py +8 -0
  261. paddle_billing/Notifications/Entities/Shared/MethodDetails.py +19 -0
  262. paddle_billing/Notifications/Entities/Shared/Money.py +28 -0
  263. paddle_billing/Notifications/Entities/Shared/Original.py +18 -0
  264. paddle_billing/Notifications/Entities/Shared/PaymentAttemptStatus.py +13 -0
  265. paddle_billing/Notifications/Entities/Shared/PaymentMethodType.py +15 -0
  266. paddle_billing/Notifications/Entities/Shared/PayoutTotalsAdjustment.py +29 -0
  267. paddle_billing/Notifications/Entities/Shared/PriceQuantity.py +16 -0
  268. paddle_billing/Notifications/Entities/Shared/Status.py +6 -0
  269. paddle_billing/Notifications/Entities/Shared/TaxCategory.py +13 -0
  270. paddle_billing/Notifications/Entities/Shared/TaxMode.py +7 -0
  271. paddle_billing/Notifications/Entities/Shared/TaxRatesUsed.py +18 -0
  272. paddle_billing/Notifications/Entities/Shared/TimePeriod.py +18 -0
  273. paddle_billing/Notifications/Entities/Shared/Totals.py +20 -0
  274. paddle_billing/Notifications/Entities/Shared/TransactionOrigin.py +10 -0
  275. paddle_billing/Notifications/Entities/Shared/TransactionPaymentAttempt.py +35 -0
  276. paddle_billing/Notifications/Entities/Shared/TransactionPayoutTotals.py +36 -0
  277. paddle_billing/Notifications/Entities/Shared/TransactionPayoutTotalsAdjusted.py +29 -0
  278. paddle_billing/Notifications/Entities/Shared/TransactionStatus.py +11 -0
  279. paddle_billing/Notifications/Entities/Shared/TransactionTotals.py +36 -0
  280. paddle_billing/Notifications/Entities/Shared/TransactionTotalsAdjusted.py +28 -0
  281. paddle_billing/Notifications/Entities/Shared/UnitPriceOverride.py +19 -0
  282. paddle_billing/Notifications/Entities/Shared/UnitTotals.py +20 -0
  283. paddle_billing/Notifications/Entities/Shared/__init__.py +46 -0
  284. paddle_billing/Notifications/Entities/Subscription.py +76 -0
  285. paddle_billing/Notifications/Entities/Subscriptions/SubscriptionAdjustmentItem.py +24 -0
  286. paddle_billing/Notifications/Entities/Subscriptions/SubscriptionCharge.py +18 -0
  287. paddle_billing/Notifications/Entities/Subscriptions/SubscriptionCredit.py +18 -0
  288. paddle_billing/Notifications/Entities/Subscriptions/SubscriptionDiscount.py +19 -0
  289. paddle_billing/Notifications/Entities/Subscriptions/SubscriptionEffectiveFrom.py +6 -0
  290. paddle_billing/Notifications/Entities/Subscriptions/SubscriptionItem.py +35 -0
  291. paddle_billing/Notifications/Entities/Subscriptions/SubscriptionItemStatus.py +7 -0
  292. paddle_billing/Notifications/Entities/Subscriptions/SubscriptionOnPaymentFailure.py +6 -0
  293. paddle_billing/Notifications/Entities/Subscriptions/SubscriptionPrice.py +28 -0
  294. paddle_billing/Notifications/Entities/Subscriptions/SubscriptionScheduledChange.py +21 -0
  295. paddle_billing/Notifications/Entities/Subscriptions/SubscriptionScheduledChangeAction.py +7 -0
  296. paddle_billing/Notifications/Entities/Subscriptions/SubscriptionStatus.py +10 -0
  297. paddle_billing/Notifications/Entities/Subscriptions/SubscriptionTimePeriod.py +17 -0
  298. paddle_billing/Notifications/Entities/Subscriptions/__init__.py +13 -0
  299. paddle_billing/Notifications/Entities/Transaction.py +75 -0
  300. paddle_billing/Notifications/Entities/Transactions/TransactionAdjustmentsTotals.py +30 -0
  301. paddle_billing/Notifications/Entities/Transactions/TransactionBreakdown.py +18 -0
  302. paddle_billing/Notifications/Entities/Transactions/TransactionCardType.py +14 -0
  303. paddle_billing/Notifications/Entities/Transactions/TransactionDetails.py +32 -0
  304. paddle_billing/Notifications/Entities/Transactions/TransactionItem.py +24 -0
  305. paddle_billing/Notifications/Entities/Transactions/TransactionLineItem.py +35 -0
  306. paddle_billing/Notifications/Entities/Transactions/TransactionProration.py +18 -0
  307. paddle_billing/Notifications/Entities/Transactions/TransactionTimePeriod.py +17 -0
  308. paddle_billing/Notifications/Entities/Transactions/__init__.py +11 -0
  309. paddle_billing/Notifications/Entities/__init__.py +0 -0
  310. paddle_billing/Notifications/Events/AddressCreated.py +17 -0
  311. paddle_billing/Notifications/Events/AddressUpdated.py +17 -0
  312. paddle_billing/Notifications/Events/AdjustmentCreated.py +17 -0
  313. paddle_billing/Notifications/Events/AdjustmentUpdated.py +17 -0
  314. paddle_billing/Notifications/Events/BusinessCreated.py +17 -0
  315. paddle_billing/Notifications/Events/BusinessUpdated.py +17 -0
  316. paddle_billing/Notifications/Events/CustomerCreated.py +17 -0
  317. paddle_billing/Notifications/Events/CustomerUpdated.py +17 -0
  318. paddle_billing/Notifications/Events/DiscountCreated.py +17 -0
  319. paddle_billing/Notifications/Events/DiscountImported.py +17 -0
  320. paddle_billing/Notifications/Events/DiscountUpdated.py +17 -0
  321. paddle_billing/Notifications/Events/PayoutCreated.py +17 -0
  322. paddle_billing/Notifications/Events/PayoutPaid.py +17 -0
  323. paddle_billing/Notifications/Events/PriceCreated.py +17 -0
  324. paddle_billing/Notifications/Events/PriceUpdated.py +17 -0
  325. paddle_billing/Notifications/Events/ProductCreated.py +17 -0
  326. paddle_billing/Notifications/Events/ProductUpdated.py +17 -0
  327. paddle_billing/Notifications/Events/ReportCreated.py +17 -0
  328. paddle_billing/Notifications/Events/ReportUpdated.py +17 -0
  329. paddle_billing/Notifications/Events/SubscriptionActivated.py +17 -0
  330. paddle_billing/Notifications/Events/SubscriptionCanceled.py +17 -0
  331. paddle_billing/Notifications/Events/SubscriptionCreated.py +17 -0
  332. paddle_billing/Notifications/Events/SubscriptionImported.py +17 -0
  333. paddle_billing/Notifications/Events/SubscriptionPastDue.py +17 -0
  334. paddle_billing/Notifications/Events/SubscriptionPaused.py +17 -0
  335. paddle_billing/Notifications/Events/SubscriptionResumed.py +17 -0
  336. paddle_billing/Notifications/Events/SubscriptionTrialing.py +17 -0
  337. paddle_billing/Notifications/Events/SubscriptionUpdated.py +17 -0
  338. paddle_billing/Notifications/Events/TransactionBilled.py +17 -0
  339. paddle_billing/Notifications/Events/TransactionCanceled.py +17 -0
  340. paddle_billing/Notifications/Events/TransactionCompleted.py +16 -0
  341. paddle_billing/Notifications/Events/TransactionCreated.py +17 -0
  342. paddle_billing/Notifications/Events/TransactionPaid.py +17 -0
  343. paddle_billing/Notifications/Events/TransactionPastDue.py +17 -0
  344. paddle_billing/Notifications/Events/TransactionPaymentFailed.py +17 -0
  345. paddle_billing/Notifications/Events/TransactionReady.py +17 -0
  346. paddle_billing/Notifications/Events/TransactionUpdated.py +17 -0
  347. paddle_billing/Notifications/Events/__init__.py +0 -0
  348. paddle_billing/Notifications/PaddleSignature.py +128 -0
  349. paddle_billing/Notifications/Secret.py +8 -0
  350. paddle_billing/Notifications/Verifier.py +55 -0
  351. paddle_billing/Notifications/__init__.py +3 -0
  352. paddle_billing/Options.py +10 -0
  353. paddle_billing/PaddleStrEnum.py +44 -0
  354. paddle_billing/RecursivelyRemoveKey.py +14 -0
  355. paddle_billing/Resources/Addresses/AddressesClient.py +58 -0
  356. paddle_billing/Resources/Addresses/Operations/CreateAddress.py +20 -0
  357. paddle_billing/Resources/Addresses/Operations/ListAddresses.py +42 -0
  358. paddle_billing/Resources/Addresses/Operations/UpdateAddress.py +21 -0
  359. paddle_billing/Resources/Addresses/Operations/__init__.py +3 -0
  360. paddle_billing/Resources/Addresses/__init__.py +0 -0
  361. paddle_billing/Resources/Adjustments/AdjustmentsClient.py +36 -0
  362. paddle_billing/Resources/Adjustments/Operations/Create/AdjustmentItem.py +11 -0
  363. paddle_billing/Resources/Adjustments/Operations/Create/__init__.py +0 -0
  364. paddle_billing/Resources/Adjustments/Operations/CreateAdjustment.py +28 -0
  365. paddle_billing/Resources/Adjustments/Operations/ListAdjustments.py +60 -0
  366. paddle_billing/Resources/Adjustments/Operations/__init__.py +3 -0
  367. paddle_billing/Resources/Adjustments/__init__.py +0 -0
  368. paddle_billing/Resources/Businesses/BusinessesClient.py +58 -0
  369. paddle_billing/Resources/Businesses/Operations/CreateBusiness.py +17 -0
  370. paddle_billing/Resources/Businesses/Operations/ListBusinesses.py +45 -0
  371. paddle_billing/Resources/Businesses/Operations/UpdateBusiness.py +18 -0
  372. paddle_billing/Resources/Businesses/Operations/__init__.py +3 -0
  373. paddle_billing/Resources/Businesses/__init__.py +0 -0
  374. paddle_billing/Resources/Customers/CustomersClient.py +65 -0
  375. paddle_billing/Resources/Customers/Operations/CreateCustomer.py +16 -0
  376. paddle_billing/Resources/Customers/Operations/ListCreditBalances.py +28 -0
  377. paddle_billing/Resources/Customers/Operations/ListCustomers.py +50 -0
  378. paddle_billing/Resources/Customers/Operations/UpdateCustomer.py +17 -0
  379. paddle_billing/Resources/Customers/Operations/__init__.py +4 -0
  380. paddle_billing/Resources/Customers/__init__.py +0 -0
  381. paddle_billing/Resources/Discounts/DiscountsClient.py +55 -0
  382. paddle_billing/Resources/Discounts/Operations/CreateDiscount.py +24 -0
  383. paddle_billing/Resources/Discounts/Operations/ListDiscounts.py +46 -0
  384. paddle_billing/Resources/Discounts/Operations/UpdateDiscount.py +25 -0
  385. paddle_billing/Resources/Discounts/Operations/__init__.py +3 -0
  386. paddle_billing/Resources/Discounts/__init__.py +0 -0
  387. paddle_billing/Resources/EventTypes/EventTypesClient.py +22 -0
  388. paddle_billing/Resources/EventTypes/__init__.py +0 -0
  389. paddle_billing/Resources/Events/EventsClient.py +26 -0
  390. paddle_billing/Resources/Events/Operations/ListEvents.py +12 -0
  391. paddle_billing/Resources/Events/Operations/__init__.py +1 -0
  392. paddle_billing/Resources/Events/__init__.py +0 -0
  393. paddle_billing/Resources/NotificationLogs/NotificationLogsClient.py +26 -0
  394. paddle_billing/Resources/NotificationLogs/Operations/ListNotificationLogs.py +11 -0
  395. paddle_billing/Resources/NotificationLogs/Operations/__init__.py +1 -0
  396. paddle_billing/Resources/NotificationLogs/__init__.py +0 -0
  397. paddle_billing/Resources/NotificationSettings/NotificationSettingsClient.py +54 -0
  398. paddle_billing/Resources/NotificationSettings/Operations/CreateNotificationSetting.py +21 -0
  399. paddle_billing/Resources/NotificationSettings/Operations/UpdateNotificationSetting.py +20 -0
  400. paddle_billing/Resources/NotificationSettings/Operations/__init__.py +2 -0
  401. paddle_billing/Resources/NotificationSettings/__init__.py +0 -0
  402. paddle_billing/Resources/Notifications/NotificationsClient.py +44 -0
  403. paddle_billing/Resources/Notifications/Operations/ListNotifications.py +58 -0
  404. paddle_billing/Resources/Notifications/Operations/__init__.py +1 -0
  405. paddle_billing/Resources/Notifications/__init__.py +0 -0
  406. paddle_billing/Resources/Prices/Operations/CreatePrice.py +23 -0
  407. paddle_billing/Resources/Prices/Operations/List/Includes.py +5 -0
  408. paddle_billing/Resources/Prices/Operations/List/__init__.py +0 -0
  409. paddle_billing/Resources/Prices/Operations/ListPrices.py +62 -0
  410. paddle_billing/Resources/Prices/Operations/UpdatePrice.py +23 -0
  411. paddle_billing/Resources/Prices/Operations/__init__.py +4 -0
  412. paddle_billing/Resources/Prices/PricesClient.py +65 -0
  413. paddle_billing/Resources/Prices/__init__.py +0 -0
  414. paddle_billing/Resources/PricingPreviews/Operations/PreviewPrice.py +20 -0
  415. paddle_billing/Resources/PricingPreviews/Operations/__init__.py +1 -0
  416. paddle_billing/Resources/PricingPreviews/PricingPreviewsClient.py +20 -0
  417. paddle_billing/Resources/PricingPreviews/__init__.py +0 -0
  418. paddle_billing/Resources/Products/Operations/CreateProduct.py +18 -0
  419. paddle_billing/Resources/Products/Operations/List/Includes.py +5 -0
  420. paddle_billing/Resources/Products/Operations/List/__init__.py +0 -0
  421. paddle_billing/Resources/Products/Operations/ListProducts.py +59 -0
  422. paddle_billing/Resources/Products/Operations/UpdateProduct.py +19 -0
  423. paddle_billing/Resources/Products/Operations/__init__.py +4 -0
  424. paddle_billing/Resources/Products/ProductsClient.py +70 -0
  425. paddle_billing/Resources/Products/__init__.py +0 -0
  426. paddle_billing/Resources/Reports/Operations/CreateReport.py +27 -0
  427. paddle_billing/Resources/Reports/Operations/ListReports.py +35 -0
  428. paddle_billing/Resources/Reports/Operations/__init__.py +2 -0
  429. paddle_billing/Resources/Reports/ReportsClient.py +51 -0
  430. paddle_billing/Resources/Reports/__init__.py +0 -0
  431. paddle_billing/Resources/Shared/Operations/List/Comparator.py +8 -0
  432. paddle_billing/Resources/Shared/Operations/List/DateComparison.py +31 -0
  433. paddle_billing/Resources/Shared/Operations/List/OrderBy.py +21 -0
  434. paddle_billing/Resources/Shared/Operations/List/Pager.py +24 -0
  435. paddle_billing/Resources/Shared/Operations/List/__init__.py +0 -0
  436. paddle_billing/Resources/Shared/Operations/__init__.py +4 -0
  437. paddle_billing/Resources/Shared/__init__.py +0 -0
  438. paddle_billing/Resources/Subscriptions/Operations/CancelSubscription.py +12 -0
  439. paddle_billing/Resources/Subscriptions/Operations/CreateOneTimeCharge.py +22 -0
  440. paddle_billing/Resources/Subscriptions/Operations/Get/Includes.py +6 -0
  441. paddle_billing/Resources/Subscriptions/Operations/Get/__init__.py +0 -0
  442. paddle_billing/Resources/Subscriptions/Operations/ListSubscriptions.py +59 -0
  443. paddle_billing/Resources/Subscriptions/Operations/PauseSubscription.py +19 -0
  444. paddle_billing/Resources/Subscriptions/Operations/PreviewOneTimeCharge.py +22 -0
  445. paddle_billing/Resources/Subscriptions/Operations/PreviewUpdateSubscription.py +37 -0
  446. paddle_billing/Resources/Subscriptions/Operations/ResumeSubscription.py +17 -0
  447. paddle_billing/Resources/Subscriptions/Operations/Update/SubscriptionDiscount.py +9 -0
  448. paddle_billing/Resources/Subscriptions/Operations/Update/__init__.py +0 -0
  449. paddle_billing/Resources/Subscriptions/Operations/UpdateSubscription.py +37 -0
  450. paddle_billing/Resources/Subscriptions/Operations/__init__.py +10 -0
  451. paddle_billing/Resources/Subscriptions/SubscriptionsClient.py +121 -0
  452. paddle_billing/Resources/Subscriptions/__init__.py +0 -0
  453. paddle_billing/Resources/Transactions/Operations/CreateTransaction.py +25 -0
  454. paddle_billing/Resources/Transactions/Operations/List/Includes.py +11 -0
  455. paddle_billing/Resources/Transactions/Operations/List/Origin.py +10 -0
  456. paddle_billing/Resources/Transactions/Operations/List/__init__.py +0 -0
  457. paddle_billing/Resources/Transactions/Operations/ListTransactions.py +86 -0
  458. paddle_billing/Resources/Transactions/Operations/PreviewTransaction.py +24 -0
  459. paddle_billing/Resources/Transactions/Operations/UpdateTransaction.py +25 -0
  460. paddle_billing/Resources/Transactions/Operations/__init__.py +6 -0
  461. paddle_billing/Resources/Transactions/TransactionsClient.py +90 -0
  462. paddle_billing/Resources/Transactions/__init__.py +0 -0
  463. paddle_billing/Resources/__init__.py +0 -0
  464. paddle_billing/ResponseParser.py +65 -0
  465. paddle_billing/Undefined.py +2 -0
  466. paddle_billing/__init__.py +4 -0
  467. paddle_python_sdk-0.1.0.dist-info/LICENSE +190 -0
  468. paddle_python_sdk-0.1.0.dist-info/METADATA +184 -0
  469. paddle_python_sdk-0.1.0.dist-info/RECORD +517 -0
  470. paddle_python_sdk-0.1.0.dist-info/WHEEL +5 -0
  471. paddle_python_sdk-0.1.0.dist-info/top_level.txt +3 -0
  472. tests/Functional/Resources/Addresses/__init__.py +0 -0
  473. tests/Functional/Resources/Addresses/test_AddressesClient.py +274 -0
  474. tests/Functional/Resources/Adjustments/__init__.py +0 -0
  475. tests/Functional/Resources/Adjustments/test_AdjustmentsClient.py +188 -0
  476. tests/Functional/Resources/Businesses/__init__.py +0 -0
  477. tests/Functional/Resources/Businesses/test_BusinessesClient.py +279 -0
  478. tests/Functional/Resources/Customers/__init__.py +0 -0
  479. tests/Functional/Resources/Customers/test_CustomersClient.py +291 -0
  480. tests/Functional/Resources/Discounts/__init__.py +0 -0
  481. tests/Functional/Resources/Discounts/test_DiscountsClient.py +280 -0
  482. tests/Functional/Resources/EventTypes/__init__.py +0 -0
  483. tests/Functional/Resources/EventTypes/test_EventTypesClient.py +43 -0
  484. tests/Functional/Resources/Events/__init__.py +0 -0
  485. tests/Functional/Resources/Events/test_EventsClient.py +64 -0
  486. tests/Functional/Resources/NotificationLogs/__init__.py +0 -0
  487. tests/Functional/Resources/NotificationLogs/test_NotificationLogsClient.py +68 -0
  488. tests/Functional/Resources/NotificationSettings/__init__.py +0 -0
  489. tests/Functional/Resources/NotificationSettings/test_NotificationSettingsClient.py +287 -0
  490. tests/Functional/Resources/Notifications/__init__.py +0 -0
  491. tests/Functional/Resources/Notifications/test_NotificationsClient.py +202 -0
  492. tests/Functional/Resources/Prices/__init__.py +0 -0
  493. tests/Functional/Resources/Prices/test_PricesClient.py +307 -0
  494. tests/Functional/Resources/PricingPreviews/__init__.py +0 -0
  495. tests/Functional/Resources/PricingPreviews/test_PricingPreviewsClient.py +92 -0
  496. tests/Functional/Resources/Products/__init__.py +0 -0
  497. tests/Functional/Resources/Products/test_ProductsClient.py +271 -0
  498. tests/Functional/Resources/Reports/__init__.py +0 -0
  499. tests/Functional/Resources/Reports/test_ReportsClient.py +197 -0
  500. tests/Functional/Resources/Subscriptions/__init__.py +0 -0
  501. tests/Functional/Resources/Subscriptions/test_SubscriptionsClient.py +758 -0
  502. tests/Functional/Resources/Transactions/__init__.py +0 -0
  503. tests/Functional/Resources/Transactions/test_TransactionsClient.py +585 -0
  504. tests/Functional/Resources/__init__.py +0 -0
  505. tests/Functional/__init__.py +0 -0
  506. tests/Unit/Logger/__init__.py +0 -0
  507. tests/Unit/Logger/test_Logger.py +10 -0
  508. tests/Unit/Notification/__init__.py +0 -0
  509. tests/Unit/Notification/test_Verifier.py +63 -0
  510. tests/Unit/PaddleStrEnum/__init__.py +0 -0
  511. tests/Unit/PaddleStrEnum/test_PaddleStrEnum.py +52 -0
  512. tests/Unit/__init__.py +0 -0
  513. tests/Utils/FakeResponse.py +6 -0
  514. tests/Utils/ReadsFixture.py +33 -0
  515. tests/Utils/TestClient.py +48 -0
  516. tests/Utils/__init__.py +1 -0
  517. tests/__init__.py +0 -0
@@ -0,0 +1,758 @@
1
+ from json import loads
2
+ from pytest import mark
3
+ from urllib.parse import unquote
4
+
5
+ from paddle_billing.Entities.Collections import SubscriptionCollection
6
+ from paddle_billing.Entities.DateTime import DateTime
7
+ from paddle_billing.Entities.Subscription import Subscription
8
+ from paddle_billing.Entities.SubscriptionPreview import SubscriptionPreview
9
+ from paddle_billing.Entities.Transaction import Transaction
10
+
11
+ from paddle_billing.Entities.Shared import CollectionMode, CurrencyCode, CustomData
12
+ from paddle_billing.Entities.Subscriptions import (
13
+ SubscriptionEffectiveFrom,
14
+ SubscriptionItems,
15
+ SubscriptionOnPaymentFailure,
16
+ SubscriptionProrationBillingMode,
17
+ SubscriptionResumeEffectiveFrom,
18
+ SubscriptionScheduledChangeAction,
19
+ SubscriptionStatus,
20
+ )
21
+
22
+ from paddle_billing.Resources.Shared.Operations import Pager
23
+ from paddle_billing.Resources.Subscriptions.Operations import (
24
+ CancelSubscription,
25
+ CreateOneTimeCharge,
26
+ ListSubscriptions,
27
+ PauseSubscription,
28
+ PreviewOneTimeCharge,
29
+ PreviewUpdateSubscription,
30
+ ResumeSubscription,
31
+ SubscriptionDiscount,
32
+ SubscriptionIncludes,
33
+ UpdateSubscription,
34
+ )
35
+
36
+ from tests.Utils.TestClient import mock_requests, test_client
37
+ from tests.Utils.ReadsFixture import ReadsFixtures
38
+
39
+
40
+ class TestSubscriptionsClient:
41
+ @mark.parametrize(
42
+ 'subscription_id, operation, expected_request_body, expected_response_status, expected_response_body, expected_url',
43
+ [
44
+ (
45
+ 'sub_01h8bx8fmywym11t6swgzba704',
46
+ UpdateSubscription(proration_billing_mode=SubscriptionProrationBillingMode.ProratedNextBillingPeriod),
47
+ ReadsFixtures.read_raw_json_fixture('request/update_single'),
48
+ 200,
49
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
50
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704',
51
+ ), (
52
+ 'sub_01h8bx8fmywym11t6swgzba704',
53
+ UpdateSubscription(
54
+ proration_billing_mode = SubscriptionProrationBillingMode.FullImmediately,
55
+ scheduled_change = None,
56
+ ),
57
+ ReadsFixtures.read_raw_json_fixture('request/update_partial'),
58
+ 200,
59
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
60
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704',
61
+ ), (
62
+ 'sub_01h8bx8fmywym11t6swgzba704',
63
+ UpdateSubscription(
64
+ customer_id = 'ctm_01h8441jn5pcwrfhwh78jqt8hk',
65
+ address_id = 'add_01h848pep46enq8y372x7maj0p',
66
+ business_id = None,
67
+ currency_code = CurrencyCode.GBP,
68
+ next_billed_at = DateTime('2023-11-06 14:00:00'),
69
+ collection_mode = CollectionMode.Automatic,
70
+ billing_details = None,
71
+ scheduled_change = None,
72
+ proration_billing_mode = SubscriptionProrationBillingMode.FullImmediately,
73
+ custom_data = CustomData({'early_access': True}),
74
+ discount = SubscriptionDiscount(
75
+ 'dsc_01h848pep46enq8y372x7maj0p',
76
+ SubscriptionEffectiveFrom.NextBillingPeriod,
77
+ ),
78
+ items = [
79
+ SubscriptionItems('pri_01gsz91wy9k1yn7kx82aafwvea', 1),
80
+ SubscriptionItems('pri_01gsz91wy9k1yn7kx82bafwvea', 5),
81
+ ],
82
+ ),
83
+ ReadsFixtures.read_raw_json_fixture('request/update_full'),
84
+ 200,
85
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
86
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704',
87
+ ),
88
+ ],
89
+ ids=[
90
+ "Update subscription with a single new value",
91
+ "Update subscription with partial new values",
92
+ "Update subscription with all new values",
93
+ ],
94
+ )
95
+ def test_update_subscription_uses_expected_payload(
96
+ self,
97
+ test_client,
98
+ mock_requests,
99
+ subscription_id,
100
+ operation,
101
+ expected_request_body,
102
+ expected_response_status,
103
+ expected_response_body,
104
+ expected_url,
105
+ ):
106
+ expected_url = f"{test_client.base_url}{expected_url}"
107
+ mock_requests.patch(expected_url, status_code=expected_response_status, text=expected_response_body)
108
+
109
+ response = test_client.client.subscriptions.update(subscription_id, operation=operation)
110
+ response_json = test_client.client.subscriptions.response.json()
111
+ request_json = test_client.client.payload
112
+ last_request = mock_requests.last_request
113
+
114
+ assert isinstance(response, Subscription)
115
+ assert last_request is not None
116
+ assert last_request.method == 'PATCH'
117
+ assert test_client.client.status_code == expected_response_status
118
+ assert unquote(last_request.url) == expected_url, \
119
+ "The URL does not match the expected URL, verify the query string is correct"
120
+ assert loads(request_json) == loads(expected_request_body), \
121
+ "The request JSON doesn't match the expected fixture JSON"
122
+ assert response_json == loads(str(expected_response_body)), \
123
+ "The response JSON doesn't match the expected fixture JSON"
124
+
125
+
126
+ @mark.parametrize(
127
+ 'operation, expected_response_status, expected_response_body, expected_url',
128
+ [
129
+ (
130
+ ListSubscriptions(),
131
+ 200,
132
+ ReadsFixtures.read_raw_json_fixture('response/list_default'),
133
+ '/subscriptions',
134
+ ), (
135
+ ListSubscriptions(Pager()),
136
+ 200,
137
+ ReadsFixtures.read_raw_json_fixture('response/list_default'),
138
+ '/subscriptions?order_by=id[asc]&per_page=50',
139
+ ), (
140
+ ListSubscriptions(Pager(after='sub_01h848pep46enq8y372x7maj0p')),
141
+ 200,
142
+ ReadsFixtures.read_raw_json_fixture('response/list_default'),
143
+ '/subscriptions?after=sub_01h848pep46enq8y372x7maj0p&order_by=id[asc]&per_page=50',
144
+ ), (
145
+ ListSubscriptions(statuses=[SubscriptionStatus.Paused]),
146
+ 200,
147
+ ReadsFixtures.read_raw_json_fixture('response/list_default'),
148
+ '/subscriptions?status=paused',
149
+ ), (
150
+ ListSubscriptions(ids=['sub_01h848pep46enq8y372x7maj0p']),
151
+ 200,
152
+ ReadsFixtures.read_raw_json_fixture('response/list_default'),
153
+ '/subscriptions?id=sub_01h848pep46enq8y372x7maj0p',
154
+ ), (
155
+ ListSubscriptions(ids=['sub_01h8494f4w5rwfp8b12yqh8fp1', 'sub_01h848pep46enq8y372x7maj0p']),
156
+ 200,
157
+ ReadsFixtures.read_raw_json_fixture('response/list_default'),
158
+ '/subscriptions?id=sub_01h8494f4w5rwfp8b12yqh8fp1,sub_01h848pep46enq8y372x7maj0p',
159
+ ), (
160
+ ListSubscriptions(collection_mode=CollectionMode.Automatic),
161
+ 200,
162
+ ReadsFixtures.read_raw_json_fixture('response/list_default'),
163
+ '/subscriptions?collection_mode=automatic',
164
+ ), (
165
+ ListSubscriptions(address_ids=['add_01h8494f4w5rwfp8b12yqh8fp1']),
166
+ 200,
167
+ ReadsFixtures.read_raw_json_fixture('response/list_default'),
168
+ '/subscriptions?address_id=add_01h8494f4w5rwfp8b12yqh8fp1',
169
+ ), (
170
+ ListSubscriptions(address_ids=['add_01h8494f4w5rwfp8b12yqh8fp1', 'add_01h848pep46enq8y372x7maj0p']),
171
+ 200,
172
+ ReadsFixtures.read_raw_json_fixture('response/list_default'),
173
+ '/subscriptions?address_id=add_01h8494f4w5rwfp8b12yqh8fp1,add_01h848pep46enq8y372x7maj0p',
174
+ ), (
175
+ ListSubscriptions(price_ids=['pri_01h8494f4w5rwfp8b12yqh8fp1']),
176
+ 200,
177
+ ReadsFixtures.read_raw_json_fixture('response/list_default'),
178
+ '/subscriptions?price_id=pri_01h8494f4w5rwfp8b12yqh8fp1',
179
+ ), (
180
+ ListSubscriptions(price_ids=['pri_01h8494f4w5rwfp8b12yqh8fp1', 'pri_01h848pep46enq8y372x7maj0p']),
181
+ 200,
182
+ ReadsFixtures.read_raw_json_fixture('response/list_default'),
183
+ '/subscriptions?price_id=pri_01h8494f4w5rwfp8b12yqh8fp1,pri_01h848pep46enq8y372x7maj0p',
184
+ ), (
185
+ ListSubscriptions(scheduled_change_actions=[SubscriptionScheduledChangeAction.Pause]),
186
+ 200,
187
+ ReadsFixtures.read_raw_json_fixture('response/list_default'),
188
+ "/subscriptions?scheduled_change_action=pause",
189
+ ), (
190
+ ListSubscriptions(scheduled_change_actions=[
191
+ SubscriptionScheduledChangeAction.Pause,
192
+ SubscriptionScheduledChangeAction.Cancel,
193
+ ]),
194
+ 200,
195
+ ReadsFixtures.read_raw_json_fixture('response/list_default'),
196
+ '/subscriptions?scheduled_change_action=pause,cancel',
197
+ ),
198
+ ],
199
+ ids=[
200
+ "List subscriptions without pagination",
201
+ "List subscriptions with default pagination",
202
+ "List paginated subscriptions after specified subscription_id",
203
+ "List subscriptions filtered by status",
204
+ "List subscriptions filtered by id",
205
+ "List subscriptions filtered by multiple ids",
206
+ "List subscriptions filtered by automatic collection_mode",
207
+ "List subscriptions filtered by address_id",
208
+ "List subscriptions filtered by multiple address_ids",
209
+ "List subscriptions filtered by price_id",
210
+ "List subscriptions filtered by multiple price_ids",
211
+ "List subscriptions with scheduled_change_actions",
212
+ "List subscriptions with multiple scheduled_change_actions",
213
+ ],
214
+ )
215
+ def test_list_subscriptions_returns_expected_response(
216
+ self,
217
+ test_client,
218
+ mock_requests,
219
+ operation,
220
+ expected_response_status,
221
+ expected_response_body,
222
+ expected_url,
223
+ ):
224
+ expected_url = f"{test_client.base_url}{expected_url}"
225
+ mock_requests.get(expected_url, status_code=expected_response_status, text=expected_response_body)
226
+
227
+ response = test_client.client.subscriptions.list(operation)
228
+ response_json = test_client.client.subscriptions.response.json()
229
+ last_request = mock_requests.last_request
230
+
231
+ assert isinstance(response, SubscriptionCollection)
232
+ assert last_request is not None
233
+ assert last_request.method == 'GET'
234
+ assert test_client.client.status_code == expected_response_status
235
+ assert unquote(last_request.url) == expected_url, \
236
+ "The URL does not match the expected URL, verify the query string is correct"
237
+ assert response_json == loads(str(expected_response_body)), \
238
+ "The response JSON generated by ResponseParser() doesn't match the expected fixture JSON"
239
+
240
+
241
+ @mark.parametrize(
242
+ 'subscription_id, includes, expected_response_status, expected_response_body, expected_url',
243
+ [
244
+ (
245
+ 'sub_01h7zcgmdc6tmwtjehp3sh7azf',
246
+ None,
247
+ 200,
248
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
249
+ '/subscriptions/sub_01h7zcgmdc6tmwtjehp3sh7azf',
250
+ ), (
251
+ 'sub_01h7zcgmdc6tmwtjehp3sh7azf',
252
+ [SubscriptionIncludes.NextTransaction],
253
+ 200,
254
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
255
+ '/subscriptions/sub_01h7zcgmdc6tmwtjehp3sh7azf?include=next_transaction',
256
+ ),
257
+ ],
258
+ ids=[
259
+ "Get subscriptions",
260
+ "Get subscriptions with includes",
261
+ ],
262
+ )
263
+ def test_get_subscriptions_returns_expected_response(
264
+ self,
265
+ test_client,
266
+ mock_requests,
267
+ subscription_id,
268
+ includes,
269
+ expected_response_status,
270
+ expected_response_body,
271
+ expected_url,
272
+ ):
273
+ expected_url = f"{test_client.base_url}{expected_url}"
274
+ mock_requests.get(expected_url, status_code=expected_response_status, text=expected_response_body)
275
+
276
+ response = test_client.client.subscriptions.get(subscription_id, includes=includes)
277
+ response_json = test_client.client.subscriptions.response.json()
278
+ last_request = mock_requests.last_request
279
+
280
+ assert isinstance(response, Subscription)
281
+ assert last_request is not None
282
+ assert last_request.method == 'GET'
283
+ assert test_client.client.status_code == expected_response_status
284
+ assert unquote(last_request.url) == expected_url, \
285
+ "The URL does not match the expected URL, verify the query string is correct"
286
+ assert response_json == loads(str(expected_response_body)), \
287
+ "The response JSON generated by ResponseParser() doesn't match the expected fixture JSON"
288
+
289
+
290
+ @mark.parametrize(
291
+ 'subscription_id, operation, expected_request_body, expected_response_status, expected_response_body, expected_url',
292
+ [
293
+ (
294
+ 'sub_01h8bx8fmywym11t6swgzba704',
295
+ PauseSubscription(),
296
+ ReadsFixtures.read_raw_json_fixture('request/pause_none'),
297
+ 200,
298
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
299
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/pause',
300
+ ), (
301
+ 'sub_01h8bx8fmywym11t6swgzba704',
302
+ PauseSubscription(SubscriptionEffectiveFrom.NextBillingPeriod),
303
+ ReadsFixtures.read_raw_json_fixture('request/pause_single'),
304
+ 200,
305
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
306
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/pause',
307
+ ), (
308
+ 'sub_01h8bx8fmywym11t6swgzba704',
309
+ PauseSubscription(SubscriptionEffectiveFrom.NextBillingPeriod, DateTime('2023-10-09T16:30:00Z')),
310
+ ReadsFixtures.read_raw_json_fixture('request/pause_full'),
311
+ 200,
312
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
313
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/pause',
314
+ ),
315
+ ],
316
+ ids=[
317
+ "Pause subscription",
318
+ "Pause subscription as of next billing period",
319
+ "Pause subscription as of next billing period and resume at date",
320
+ ],
321
+ )
322
+ def test_pause_subscription_uses_expected_payload(
323
+ self,
324
+ test_client,
325
+ mock_requests,
326
+ subscription_id,
327
+ operation,
328
+ expected_request_body,
329
+ expected_response_status,
330
+ expected_response_body,
331
+ expected_url,
332
+ ):
333
+ expected_url = f"{test_client.base_url}{expected_url}"
334
+ mock_requests.post(expected_url, status_code=expected_response_status, text=expected_response_body)
335
+
336
+ response = test_client.client.subscriptions.pause(subscription_id, operation=operation)
337
+ response_json = test_client.client.subscriptions.response.json()
338
+ request_json = test_client.client.payload
339
+ last_request = mock_requests.last_request
340
+
341
+ assert isinstance(response, Subscription)
342
+ assert last_request is not None
343
+ assert last_request.method == 'POST'
344
+ assert test_client.client.status_code == expected_response_status
345
+ assert unquote(last_request.url) == expected_url, \
346
+ "The URL does not match the expected URL, verify the query string is correct"
347
+ assert loads(request_json) == loads(expected_request_body), \
348
+ "The request JSON doesn't match the expected fixture JSON"
349
+ assert response_json == loads(str(expected_response_body)), \
350
+ "The response JSON doesn't match the expected fixture JSON"
351
+
352
+
353
+ @mark.parametrize(
354
+ 'subscription_id, operation, expected_request_body, expected_response_status, expected_response_body, expected_url',
355
+ [
356
+ (
357
+ 'sub_01h8bx8fmywym11t6swgzba704',
358
+ ResumeSubscription(),
359
+ ReadsFixtures.read_raw_json_fixture('request/resume_none'),
360
+ 200,
361
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
362
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/resume',
363
+ ), (
364
+ 'sub_01h8bx8fmywym11t6swgzba704',
365
+ ResumeSubscription(SubscriptionResumeEffectiveFrom.Immediately),
366
+ ReadsFixtures.read_raw_json_fixture('request/resume_single_as_enum'),
367
+ 200,
368
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
369
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/resume',
370
+ ), (
371
+ 'sub_01h8bx8fmywym11t6swgzba704',
372
+ ResumeSubscription(DateTime('2023-10-09T16:30:00Z')),
373
+ ReadsFixtures.read_raw_json_fixture('request/resume_single_as_date'),
374
+ 200,
375
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
376
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/resume',
377
+ ),
378
+ ],
379
+ ids=[
380
+ "Resume subscription",
381
+ "Resume subscription with a billing period",
382
+ "Resume subscription with a new date",
383
+ ],
384
+ )
385
+ def test_resume_subscription_uses_expected_payload(
386
+ self,
387
+ test_client,
388
+ mock_requests,
389
+ subscription_id,
390
+ operation,
391
+ expected_request_body,
392
+ expected_response_status,
393
+ expected_response_body,
394
+ expected_url,
395
+ ):
396
+ expected_url = f"{test_client.base_url}{expected_url}"
397
+ mock_requests.post(expected_url, status_code=expected_response_status, text=expected_response_body)
398
+
399
+ response = test_client.client.subscriptions.resume(subscription_id, operation)
400
+ response_json = test_client.client.subscriptions.response.json()
401
+ request_json = test_client.client.payload
402
+ last_request = mock_requests.last_request
403
+
404
+ assert isinstance(response, Subscription)
405
+ assert last_request is not None
406
+ assert last_request.method == 'POST'
407
+ assert test_client.client.status_code == expected_response_status
408
+ assert unquote(last_request.url) == expected_url, \
409
+ "The URL does not match the expected URL, verify the query string is correct"
410
+ assert loads(request_json) == loads(expected_request_body), \
411
+ "The request JSON doesn't match the expected fixture JSON"
412
+ assert response_json == loads(str(expected_response_body)), \
413
+ "The response JSON doesn't match the expected fixture JSON"
414
+
415
+
416
+ @mark.parametrize(
417
+ 'subscription_id, operation, expected_request_body, expected_response_status, expected_response_body, expected_url',
418
+ [
419
+ (
420
+ 'sub_01h8bx8fmywym11t6swgzba704',
421
+ CancelSubscription(),
422
+ ReadsFixtures.read_raw_json_fixture('request/cancel_none'),
423
+ 200,
424
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
425
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/cancel',
426
+ ), (
427
+ 'sub_01h8bx8fmywym11t6swgzba704',
428
+ CancelSubscription(SubscriptionEffectiveFrom.NextBillingPeriod),
429
+ ReadsFixtures.read_raw_json_fixture('request/cancel_single'),
430
+ 200,
431
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
432
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/cancel',
433
+ ),
434
+ ],
435
+ ids=[
436
+ "Cancel subscription",
437
+ "Cancel subscription with a billing period",
438
+ ],
439
+ )
440
+ def test_cancel_subscription_uses_expected_payload(
441
+ self,
442
+ test_client,
443
+ mock_requests,
444
+ subscription_id,
445
+ operation,
446
+ expected_request_body,
447
+ expected_response_status,
448
+ expected_response_body,
449
+ expected_url,
450
+ ):
451
+ expected_url = f"{test_client.base_url}{expected_url}"
452
+ mock_requests.post(expected_url, status_code=expected_response_status, text=expected_response_body)
453
+
454
+ response = test_client.client.subscriptions.cancel(subscription_id, operation)
455
+ response_json = test_client.client.subscriptions.response.json()
456
+ request_json = test_client.client.payload
457
+ last_request = mock_requests.last_request
458
+
459
+ assert isinstance(response, Subscription)
460
+ assert last_request is not None
461
+ assert last_request.method == 'POST'
462
+ assert test_client.client.status_code == expected_response_status
463
+ assert unquote(last_request.url) == expected_url, \
464
+ "The URL does not match the expected URL, verify the query string is correct"
465
+ assert loads(request_json) == loads(expected_request_body), \
466
+ "The request JSON doesn't match the expected fixture JSON"
467
+ assert response_json == loads(str(expected_response_body)), \
468
+ "The response JSON doesn't match the expected fixture JSON"
469
+
470
+
471
+ @mark.parametrize(
472
+ 'subscription_id, operation, expected_response_status, expected_response_body, expected_url',
473
+ [(
474
+ 'sub_01h7zcgmdc6tmwtjehp3sh7azf',
475
+ CancelSubscription(),
476
+ 200,
477
+ ReadsFixtures.read_raw_json_fixture('response/get_payment_method_change_transaction_entity'),
478
+ '/subscriptions/sub_01h7zcgmdc6tmwtjehp3sh7azf/update-payment-method-transaction',
479
+ )],
480
+ ids=["Cancel subscription"],
481
+ )
482
+ def test_get_payment_method_change_transaction_returns_expected_response(
483
+ self,
484
+ test_client,
485
+ mock_requests,
486
+ subscription_id,
487
+ operation,
488
+ expected_response_status,
489
+ expected_response_body,
490
+ expected_url,
491
+ ):
492
+ expected_url = f"{test_client.base_url}{expected_url}"
493
+ mock_requests.get(expected_url, status_code=expected_response_status, text=expected_response_body)
494
+
495
+ response = test_client.client.subscriptions.get_payment_method_change_transaction(subscription_id)
496
+ response_json = test_client.client.subscriptions.response.json()
497
+ last_request = mock_requests.last_request
498
+
499
+ assert isinstance(response, Transaction)
500
+ assert last_request is not None
501
+ assert last_request.method == 'GET'
502
+ assert test_client.client.status_code == expected_response_status
503
+ assert unquote(last_request.url) == expected_url, \
504
+ "The URL does not match the expected URL, verify the query string is correct"
505
+ assert response_json == loads(str(expected_response_body)), \
506
+ "The response JSON doesn't match the expected fixture JSON"
507
+
508
+
509
+ @mark.parametrize(
510
+ 'subscription_id, expected_response_status, expected_response_body, expected_url',
511
+ [(
512
+ 'sub_01h8bx8fmywym11t6swgzba704',
513
+ 200,
514
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
515
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/activate',
516
+ )],
517
+ ids=["Activate trialing subscription"],
518
+ )
519
+ def test_activate_subscription_returns_expected_response(
520
+ self,
521
+ test_client,
522
+ mock_requests,
523
+ subscription_id,
524
+ expected_response_status,
525
+ expected_response_body,
526
+ expected_url,
527
+ ):
528
+ expected_url = f"{test_client.base_url}{expected_url}"
529
+ mock_requests.post(expected_url, status_code=expected_response_status, text=expected_response_body)
530
+
531
+ response = test_client.client.subscriptions.activate(subscription_id)
532
+ response_json = test_client.client.subscriptions.response.json()
533
+ last_request = mock_requests.last_request
534
+
535
+ assert isinstance(response, Subscription)
536
+ assert last_request is not None
537
+ assert last_request.method == 'POST'
538
+ assert test_client.client.status_code == expected_response_status
539
+ assert unquote(last_request.url) == expected_url, \
540
+ "The URL does not match the expected URL, verify the query string is correct"
541
+ assert response_json == loads(str(expected_response_body)), \
542
+ "The response JSON doesn't match the expected fixture JSON"
543
+
544
+
545
+ @mark.parametrize(
546
+ 'subscription_id, operation, expected_request_body, expected_response_status, expected_response_body, expected_url',
547
+ [
548
+ (
549
+ 'sub_01h8bx8fmywym11t6swgzba704',
550
+ CreateOneTimeCharge(
551
+ SubscriptionEffectiveFrom.NextBillingPeriod,
552
+ [SubscriptionItems('pri_01gsz98e27ak2tyhexptwc58yk', 1)],
553
+ ),
554
+ ReadsFixtures.read_raw_json_fixture('request/create_one_time_charge_minimal'),
555
+ 200,
556
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
557
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/charge',
558
+ ), (
559
+ 'sub_01h8bx8fmywym11t6swgzba704',
560
+ CreateOneTimeCharge(
561
+ SubscriptionEffectiveFrom.Immediately,
562
+ [
563
+ SubscriptionItems('pri_01gsz98e27ak2tyhexptwc58yk', 1),
564
+ SubscriptionItems('pri_01h7zdqstxe6djaefkqbkjy4k2', 10),
565
+ SubscriptionItems('pri_01h7zd9mzfq79850w4ryc39v38', 845),
566
+ ],
567
+ SubscriptionOnPaymentFailure.ApplyChange,
568
+ ),
569
+ ReadsFixtures.read_raw_json_fixture('request/create_one_time_charge_full'),
570
+ 200,
571
+ ReadsFixtures.read_raw_json_fixture('response/full_entity'),
572
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/charge',
573
+ ),
574
+ ],
575
+ ids=[
576
+ "Create subscription one-time payment for one item effective next billing period",
577
+ "Create subscription one-time payment for multiple items effective immediately",
578
+ ],
579
+ )
580
+ def test_create_subscription_one_time_charge_uses_expected_payload(
581
+ self,
582
+ test_client,
583
+ mock_requests,
584
+ subscription_id,
585
+ operation,
586
+ expected_request_body,
587
+ expected_response_status,
588
+ expected_response_body,
589
+ expected_url,
590
+ ):
591
+ expected_url = f"{test_client.base_url}{expected_url}"
592
+ mock_requests.post(expected_url, status_code=expected_response_status, text=expected_response_body)
593
+
594
+ response = test_client.client.subscriptions.create_one_time_charge(subscription_id, operation)
595
+ response_json = test_client.client.subscriptions.response.json()
596
+ request_json = test_client.client.payload
597
+ last_request = mock_requests.last_request
598
+
599
+ assert isinstance(response, Subscription)
600
+ assert last_request is not None
601
+ assert last_request.method == 'POST'
602
+ assert test_client.client.status_code == expected_response_status
603
+ assert unquote(last_request.url) == expected_url, \
604
+ "The URL does not match the expected URL, verify the query string is correct"
605
+ assert loads(request_json) == loads(expected_request_body), \
606
+ "The request JSON doesn't match the expected fixture JSON"
607
+ assert response_json == loads(str(expected_response_body)), \
608
+ "The response JSON doesn't match the expected fixture JSON"
609
+
610
+
611
+ @mark.parametrize(
612
+ 'subscription_id, operation, expected_request_body, expected_response_status, expected_response_body, expected_url',
613
+ [
614
+ (
615
+ 'sub_01h8bx8fmywym11t6swgzba704',
616
+ PreviewUpdateSubscription(proration_billing_mode=SubscriptionProrationBillingMode.ProratedNextBillingPeriod),
617
+ ReadsFixtures.read_raw_json_fixture('request/preview_update_single'),
618
+ 200,
619
+ ReadsFixtures.read_raw_json_fixture('response/preview_update_full_entity'),
620
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/preview',
621
+ ), (
622
+ 'sub_01h8bx8fmywym11t6swgzba704',
623
+ PreviewUpdateSubscription(
624
+ proration_billing_mode = SubscriptionProrationBillingMode.FullImmediately,
625
+ scheduled_change = None,
626
+ ),
627
+ ReadsFixtures.read_raw_json_fixture('request/preview_update_partial'),
628
+ 200,
629
+ ReadsFixtures.read_raw_json_fixture('response/preview_update_full_entity'),
630
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/preview',
631
+ ), (
632
+ 'sub_01h8bx8fmywym11t6swgzba704',
633
+ PreviewUpdateSubscription(
634
+ customer_id = 'ctm_01h8441jn5pcwrfhwh78jqt8hk',
635
+ address_id = 'add_01h848pep46enq8y372x7maj0p',
636
+ business_id = None,
637
+ currency_code = CurrencyCode.GBP,
638
+ next_billed_at = DateTime('2023-11-06 14:00:00'),
639
+ collection_mode = CollectionMode.Automatic,
640
+ billing_details = None,
641
+ scheduled_change = None,
642
+ proration_billing_mode = SubscriptionProrationBillingMode.FullImmediately,
643
+ custom_data = CustomData({'early_access': True}),
644
+ discount = SubscriptionDiscount(
645
+ 'dsc_01h848pep46enq8y372x7maj0p',
646
+ SubscriptionEffectiveFrom.NextBillingPeriod,
647
+ ),
648
+ items = [
649
+ SubscriptionItems('pri_01gsz91wy9k1yn7kx82aafwvea', 1),
650
+ SubscriptionItems('pri_01gsz91wy9k1yn7kx82bafwvea', 5),
651
+ ],
652
+ ),
653
+ ReadsFixtures.read_raw_json_fixture('request/preview_update_full'),
654
+ 200,
655
+ ReadsFixtures.read_raw_json_fixture('response/preview_update_full_entity'),
656
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/preview',
657
+ ),
658
+ ],
659
+ ids=[
660
+ "Preview updating a subscription with a single new value",
661
+ "Preview updating a subscription with partial new values",
662
+ "Preview updating a subscription with all new values",
663
+ ],
664
+ )
665
+ def test_preview_update_subscription_uses_expected_payload(
666
+ self,
667
+ test_client,
668
+ mock_requests,
669
+ subscription_id,
670
+ operation,
671
+ expected_request_body,
672
+ expected_response_status,
673
+ expected_response_body,
674
+ expected_url,
675
+ ):
676
+ expected_url = f"{test_client.base_url}{expected_url}"
677
+ mock_requests.patch(expected_url, status_code=expected_response_status, text=expected_response_body)
678
+
679
+ response = test_client.client.subscriptions.preview_update(subscription_id, operation)
680
+ response_json = test_client.client.subscriptions.response.json()
681
+ request_json = test_client.client.payload
682
+ last_request = mock_requests.last_request
683
+
684
+ assert isinstance(response, SubscriptionPreview)
685
+ assert last_request is not None
686
+ assert last_request.method == 'PATCH'
687
+ assert test_client.client.status_code == expected_response_status
688
+ assert unquote(last_request.url) == expected_url, \
689
+ "The URL does not match the expected URL, verify the query string is correct"
690
+ assert loads(request_json) == loads(expected_request_body), \
691
+ "The request JSON doesn't match the expected fixture JSON"
692
+ assert response_json == loads(str(expected_response_body)), \
693
+ "The response JSON doesn't match the expected fixture JSON"
694
+
695
+
696
+ @mark.parametrize(
697
+ 'subscription_id, operation, expected_request_body, expected_response_status, expected_response_body, expected_url',
698
+ [
699
+ (
700
+ 'sub_01h8bx8fmywym11t6swgzba704',
701
+ PreviewOneTimeCharge(
702
+ SubscriptionEffectiveFrom.NextBillingPeriod,
703
+ [SubscriptionItems('pri_01gsz98e27ak2tyhexptwc58yk', 1)]
704
+ ),
705
+ ReadsFixtures.read_raw_json_fixture('request/preview_one_time_charge_minimal'),
706
+ 200,
707
+ ReadsFixtures.read_raw_json_fixture('response/preview_update_full_entity'),
708
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/charge/preview',
709
+ ), (
710
+ 'sub_01h8bx8fmywym11t6swgzba704',
711
+ PreviewOneTimeCharge(
712
+ SubscriptionEffectiveFrom.Immediately,
713
+ [
714
+ SubscriptionItems('pri_01gsz98e27ak2tyhexptwc58yk', 1),
715
+ SubscriptionItems('pri_01h7zdqstxe6djaefkqbkjy4k2', 10),
716
+ SubscriptionItems('pri_01h7zd9mzfq79850w4ryc39v38', 845),
717
+ ],
718
+ ),
719
+ ReadsFixtures.read_raw_json_fixture('request/preview_one_time_charge_full'),
720
+ 200,
721
+ ReadsFixtures.read_raw_json_fixture('response/preview_update_full_entity'),
722
+ '/subscriptions/sub_01h8bx8fmywym11t6swgzba704/charge/preview',
723
+ ),
724
+ ],
725
+ ids=[
726
+ "Preview creating a subscription one-time payment for one item effective next billing period",
727
+ "Preview creating a subscription one-time payment for multiple items effective immediately",
728
+ ],
729
+ )
730
+ def test_preview_create_subscription_one_time_charge_uses_expected_payload(
731
+ self,
732
+ test_client,
733
+ mock_requests,
734
+ subscription_id,
735
+ operation,
736
+ expected_request_body,
737
+ expected_response_status,
738
+ expected_response_body,
739
+ expected_url,
740
+ ):
741
+ expected_url = f"{test_client.base_url}{expected_url}"
742
+ mock_requests.post(expected_url, status_code=expected_response_status, text=expected_response_body)
743
+
744
+ response = test_client.client.subscriptions.preview_one_time_charge(subscription_id, operation)
745
+ response_json = test_client.client.subscriptions.response.json()
746
+ request_json = test_client.client.payload
747
+ last_request = mock_requests.last_request
748
+
749
+ assert isinstance(response, SubscriptionPreview)
750
+ assert last_request is not None
751
+ assert last_request.method == 'POST'
752
+ assert test_client.client.status_code == expected_response_status
753
+ assert unquote(last_request.url) == expected_url, \
754
+ "The URL does not match the expected URL, verify the query string is correct"
755
+ assert loads(request_json) == loads(expected_request_body), \
756
+ "The request JSON doesn't match the expected fixture JSON"
757
+ assert response_json == loads(str(expected_response_body)), \
758
+ "The response JSON doesn't match the expected fixture JSON"