"`mode` must be one of: standard, custom"
"paddle_create_discount() validates required and conditional fields"
"`amount`, `description`, and `type` are required"

test_that("paddle_list_subscriptions() input validation works", {
expect_error(paddle_list_subscriptions(per_page = 0), "must be between 1 and 200")
expect_error(paddle_list_subscriptions(order_by = "date[ASC]"), "must be 'id\\[ASC\\]' or 'id\\[DESC\\]'")
expect_error(paddle_list_subscriptions(collection_mode = "invoice"), "must be 'automatic' or 'manual'")
expect_error(paddle_list_subscriptions(scheduled_change_action = "incorrect"), "must be 'cancel', 'pause' or 'resume'.")
expect_error(paddle_list_subscriptions(status = "incorrect"), "must be 'active', 'cancelled', 'past_due', 'paused' or 'trialing'")
test_that("paddle_list_subscriptions() works with valid inputs", {
test_that("paddle_update_subscription() validates and sends correct body", {
# Successful request with all parameters set
list(price_id = "pri_01jvpq30eqev9nmyt50rpe1zvz", quantity = 2)
custom_data = list(plan = "custom", source = "landing"),
test_that("paddle_update_subscription() validates required args", {
expect_error(paddle_update_subscription(), "must be a non-empty string")
expect_error(paddle_update_subscription("sub_01jvptej6fxyctrdt8ty45gw4k", collection_mode = "pay"), "must be 'automatic' or 'manual'")
expect_error(paddle_update_subscription("sub_01jvptej6fxyctrdt8ty45gw4k", currency_code = "CAD"), "must be one of: 'USD', 'EUR', 'GBP'")
expect_error(paddle_update_subscription("sub_01jvptej6fxyctrdt8ty45gw4k", discount = list(id = "dsc_1")), "must be a list with `id` and `effective_from`")
expect_error(paddle_update_subscription("sub_01jvptej6fxyctrdt8ty45gw4k", billing_details = "invalid"), "`billing_details` must be a list")
expect_error(paddle_update_subscription("sub_01jvptej6fxyctrdt8ty45gw4k", items = "notalist"), "`items` must be a list of lists")
expect_error(paddle_update_subscription("sub_01jvptej6fxyctrdt8ty45gw4k", items = list(list())), "Each item must include at least `price_id`")
expect_error(paddle_update_subscription("sub_01jvptej6fxyctrdt8ty45gw4k", items = list(list(price_id = "pri_1"))), "required when updating items or next_billed_at")
expect_error(paddle_update_subscription("sub_01jvptej6fxyctrdt8ty45gw4k", proration_billing_mode = "invalid"), "must be one of")
test_that("paddle_preview_subscription_update() validates and sends correct body", {
test_that("paddle_preview_subscription_update() validates required args", {
expect_error(paddle_preview_subscription_update(), "must be a non-empty string")
expect_error(paddle_preview_subscription_update("sub_01jvptej6fxyctrdt8ty45gw4k", collection_mode = "pay"), "must be 'automatic' or 'manual'")
expect_error(paddle_preview_subscription_update("sub_01jvptej6fxyctrdt8ty45gw4k", currency_code = "CAD"), "must be one of: 'USD', 'EUR', 'GBP'")
expect_error(paddle_preview_subscription_update("sub_01jvptej6fxyctrdt8ty45gw4k", discount = list(id = "dsc_1")), "must be a list with `id` and `effective_from`")
expect_error(paddle_preview_subscription_update("sub_01jvptej6fxyctrdt8ty45gw4k", billing_details = "invalid"), "`billing_details` must be a list")
expect_error(paddle_preview_subscription_update("sub_01jvptej6fxyctrdt8ty45gw4k", items = "notalist"), "`items` must be a list of lists")
expect_error(paddle_preview_subscription_update("sub_01jvptej6fxyctrdt8ty45gw4k", items = list(list())), "Each item must include at least `price_id`")
expect_error(paddle_preview_subscription_update("sub_01jvptej6fxyctrdt8ty45gw4k", items = list(list(price_id = "pri_1"))), "required when updating items or next_billed_at")
expect_error(paddle_preview_subscription_update("sub_01jvptej6fxyctrdt8ty45gw4k", proration_billing_mode = "invalid"), "must be one of")
expect_error(paddle_get_update_payment_transaction(NULL), "must be a non-empty string")
expect_error(paddle_get_update_payment_transaction(""), "must be a non-empty string")
expect_error(paddle_get_update_payment_transaction(123), "must be a non-empty string")
test_that("paddle_preview_one_time_charge() validates required args", {
"`effective_from` must be a non-empty RFC 3339 datetime string"
"`items` must be a non-empty list of charge items"
"Each item must include `price_id` and `quantity`"
items = list(list(price_id = "pri_01jvpq30eqev9nmyt50rpe1zvz"))
items = list(list(price_id = "pri_01jvpq30eqev9nmyt50rpe1zvz", quantity = 1)),
"`on_payment_failure` must be one of: 'prevent_change', 'allow_change'"
test_that("paddle_activate_trial_subscription() validates required argument", {
expect_error(paddle_activate_trial_subscription(), "`id` must be a non-empty string")
expect_error(paddle_activate_trial_subscription(""), "`id` must be a non-empty string")
effective_from <- format(seq(Sys.time(), by = "1 month", length.out = 2)[2], "%Y-%m-%dT%H:%M:%SZ")
expect_error(paddle_pause_subscription(), "`id` must be a non-empty string")
expect_error(paddle_pause_subscription("sub_01jvprmj2e0fn0ay9h0xjv375q", on_resume = "invalid"), "`on_resume` must be 'start_new_billing_period' or 'continue_billing_period'")
#expect_silent(paddle_pause_subscription("sub_01jvptej6fxyctrdt8ty45gw4k", effective_from = "immediately", resume_at = effective_from, on_resume = "start_new_billing_period"))
expect_error(paddle_resume_subscription(), "`id` must be a non-empty string")
expect_error(paddle_resume_subscription("sub_01jvptej6fxyctrdt8ty45gw4k"), "`effective_from` must be a non-empty RFC 3339 datetime string")
expect_error(paddle_resume_subscription("sub_01jvptej6fxyctrdt8ty45gw4k", effective_from = effective_from, on_resume = "invalid"),
"`on_resume` must be 'start_new_billing_period' or 'continue_billing_period'")
#expect_silent(paddle_resume_subscription("sub_01jvptej6fxyctrdt8ty45gw4k", effective_from = effective_from, on_resume = "continue_billing_period"))
expect_error(paddle_cancel_subscription(), "`id` must be a non-empty string")
expect_error(paddle_cancel_subscription(""), "`id` must be a non-empty string")
expect_error(paddle_cancel_subscription("sub_123", effective_from = 42), "`effective_from` must be one of: 'next_billing_period', 'immediately'")
# test_that("paddle_cancel_subscription() can cancel with scheduled future date", {
#   res <- paddle_cancel_subscription("sub_01jvprmj2e0fn0ay9h0xjv375q", effective_from = "immediately")