Skip to content

Commit

Permalink
Add support for Subscription Schedules
Browse files Browse the repository at this point in the history
  • Loading branch information
remi-stripe committed Jan 31, 2019
1 parent 94bafb4 commit dd7a7fc
Show file tree
Hide file tree
Showing 9 changed files with 266 additions and 69 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ sudo: false
env:
global:
# If changing this number, please also change it in `test/test_helper.rb`.
- STRIPE_MOCK_VERSION=0.42.0
- STRIPE_MOCK_VERSION=0.44.0

cache:
directories:
Expand Down
2 changes: 2 additions & 0 deletions lib/stripe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@
require "stripe/source_transaction"
require "stripe/subscription"
require "stripe/subscription_item"
require "stripe/subscription_schedule"
require "stripe/subscription_schedule_revision"
require "stripe/terminal/connection_token"
require "stripe/terminal/location"
require "stripe/terminal/reader"
Expand Down
32 changes: 32 additions & 0 deletions lib/stripe/subscription_schedule.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

module Stripe
class SubscriptionSchedule < APIResource
extend Stripe::APIOperations::List
extend Stripe::APIOperations::Create
include Stripe::APIOperations::Save
extend Stripe::APIOperations::NestedResource

OBJECT_NAME = "subscription_schedule".freeze

nested_resource_class_methods :revision,
operations: %i[retrieve list]

def cancel(params = {}, opts = {})
url = resource_url + "/cancel"
resp, opts = request(:post, url, params, opts)
initialize_from(resp.data, opts)
end

def release(params = {}, opts = {})
url = resource_url + "/release"
resp, opts = request(:post, url, params, opts)
initialize_from(resp.data, opts)
end

def revisions(params = {}, opts = {})
resp, opts = request(:get, resource_url + "/revisions", params, Util.normalize_opts(opts))
Util.convert_to_stripe_object(resp.data, opts)
end
end
end
25 changes: 25 additions & 0 deletions lib/stripe/subscription_schedule_revision.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

module Stripe
class SubscriptionScheduleRevision < APIResource
extend Stripe::APIOperations::List

OBJECT_NAME = "subscription_schedule_revision".freeze

def resource_url
if !respond_to?(:schedule) || schedule.nil?
raise NotImplementedError,
"Subscription Schedule Revisions cannot be accessed without a Subscription Schedule ID."
end
"#{SubscriptionSchedule.resource_url}/#{CGI.escape(schedule)}/revisions/#{CGI.escape(id)}"
end

def self.retrieve(_id, _opts = {})
raise NotImplementedError, "Subscription Schedule Revisions cannot be retrieved without a Subscription Schedule ID. Retrieve it using schedule.revisions.retrieve('revision_id')"
end

def self.list(_id, _opts = {})
raise NotImplementedError, "Subscription Schedule Revisions cannot be listed without a Subscription Schedule ID. List those using schedule.revisions"
end
end
end
136 changes: 69 additions & 67 deletions lib/stripe/util.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,73 +45,75 @@ def self.object_classes # rubocop:disable Metrics/MethodLength
ListObject::OBJECT_NAME => ListObject,

# business objects
Account::OBJECT_NAME => Account,
AccountLink::OBJECT_NAME => AccountLink,
AlipayAccount::OBJECT_NAME => AlipayAccount,
ApplePayDomain::OBJECT_NAME => ApplePayDomain,
ApplicationFee::OBJECT_NAME => ApplicationFee,
ApplicationFeeRefund::OBJECT_NAME => ApplicationFeeRefund,
Balance::OBJECT_NAME => Balance,
BalanceTransaction::OBJECT_NAME => BalanceTransaction,
BankAccount::OBJECT_NAME => BankAccount,
BitcoinReceiver::OBJECT_NAME => BitcoinReceiver,
BitcoinTransaction::OBJECT_NAME => BitcoinTransaction,
Card::OBJECT_NAME => Card,
Charge::OBJECT_NAME => Charge,
Checkout::Session::OBJECT_NAME => Checkout::Session,
CountrySpec::OBJECT_NAME => CountrySpec,
Coupon::OBJECT_NAME => Coupon,
Customer::OBJECT_NAME => Customer,
Dispute::OBJECT_NAME => Dispute,
EphemeralKey::OBJECT_NAME => EphemeralKey,
Event::OBJECT_NAME => Event,
ExchangeRate::OBJECT_NAME => ExchangeRate,
File::OBJECT_NAME => File,
File::OBJECT_NAME_ALT => File,
FileLink::OBJECT_NAME => FileLink,
Invoice::OBJECT_NAME => Invoice,
InvoiceItem::OBJECT_NAME => InvoiceItem,
InvoiceLineItem::OBJECT_NAME => InvoiceLineItem,
IssuerFraudRecord::OBJECT_NAME => IssuerFraudRecord,
Issuing::Authorization::OBJECT_NAME => Issuing::Authorization,
Issuing::Card::OBJECT_NAME => Issuing::Card,
Issuing::CardDetails::OBJECT_NAME => Issuing::CardDetails,
Issuing::Cardholder::OBJECT_NAME => Issuing::Cardholder,
Issuing::Dispute::OBJECT_NAME => Issuing::Dispute,
Issuing::Transaction::OBJECT_NAME => Issuing::Transaction,
LoginLink::OBJECT_NAME => LoginLink,
Order::OBJECT_NAME => Order,
OrderReturn::OBJECT_NAME => OrderReturn,
PaymentIntent::OBJECT_NAME => PaymentIntent,
Payout::OBJECT_NAME => Payout,
Person::OBJECT_NAME => Person,
Plan::OBJECT_NAME => Plan,
Product::OBJECT_NAME => Product,
Radar::ValueList::OBJECT_NAME => Radar::ValueList,
Radar::ValueListItem::OBJECT_NAME => Radar::ValueListItem,
Recipient::OBJECT_NAME => Recipient,
RecipientTransfer::OBJECT_NAME => RecipientTransfer,
Refund::OBJECT_NAME => Refund,
Reporting::ReportRun::OBJECT_NAME => Reporting::ReportRun,
Reporting::ReportType::OBJECT_NAME => Reporting::ReportType,
Reversal::OBJECT_NAME => Reversal,
Review::OBJECT_NAME => Review,
SKU::OBJECT_NAME => SKU,
Sigma::ScheduledQueryRun::OBJECT_NAME => Sigma::ScheduledQueryRun,
Source::OBJECT_NAME => Source,
SourceTransaction::OBJECT_NAME => SourceTransaction,
Subscription::OBJECT_NAME => Subscription,
SubscriptionItem::OBJECT_NAME => SubscriptionItem,
Terminal::ConnectionToken::OBJECT_NAME => Terminal::ConnectionToken,
Terminal::Location::OBJECT_NAME => Terminal::Location,
Terminal::Reader::OBJECT_NAME => Terminal::Reader,
ThreeDSecure::OBJECT_NAME => ThreeDSecure,
Token::OBJECT_NAME => Token,
Topup::OBJECT_NAME => Topup,
Transfer::OBJECT_NAME => Transfer,
UsageRecord::OBJECT_NAME => UsageRecord,
UsageRecordSummary::OBJECT_NAME => UsageRecordSummary,
WebhookEndpoint::OBJECT_NAME => WebhookEndpoint,
Account::OBJECT_NAME => Account,
AccountLink::OBJECT_NAME => AccountLink,
AlipayAccount::OBJECT_NAME => AlipayAccount,
ApplePayDomain::OBJECT_NAME => ApplePayDomain,
ApplicationFee::OBJECT_NAME => ApplicationFee,
ApplicationFeeRefund::OBJECT_NAME => ApplicationFeeRefund,
Balance::OBJECT_NAME => Balance,
BalanceTransaction::OBJECT_NAME => BalanceTransaction,
BankAccount::OBJECT_NAME => BankAccount,
BitcoinReceiver::OBJECT_NAME => BitcoinReceiver,
BitcoinTransaction::OBJECT_NAME => BitcoinTransaction,
Card::OBJECT_NAME => Card,
Charge::OBJECT_NAME => Charge,
Checkout::Session::OBJECT_NAME => Checkout::Session,
CountrySpec::OBJECT_NAME => CountrySpec,
Coupon::OBJECT_NAME => Coupon,
Customer::OBJECT_NAME => Customer,
Dispute::OBJECT_NAME => Dispute,
EphemeralKey::OBJECT_NAME => EphemeralKey,
Event::OBJECT_NAME => Event,
ExchangeRate::OBJECT_NAME => ExchangeRate,
File::OBJECT_NAME => File,
File::OBJECT_NAME_ALT => File,
FileLink::OBJECT_NAME => FileLink,
Invoice::OBJECT_NAME => Invoice,
InvoiceItem::OBJECT_NAME => InvoiceItem,
InvoiceLineItem::OBJECT_NAME => InvoiceLineItem,
IssuerFraudRecord::OBJECT_NAME => IssuerFraudRecord,
Issuing::Authorization::OBJECT_NAME => Issuing::Authorization,
Issuing::Card::OBJECT_NAME => Issuing::Card,
Issuing::CardDetails::OBJECT_NAME => Issuing::CardDetails,
Issuing::Cardholder::OBJECT_NAME => Issuing::Cardholder,
Issuing::Dispute::OBJECT_NAME => Issuing::Dispute,
Issuing::Transaction::OBJECT_NAME => Issuing::Transaction,
LoginLink::OBJECT_NAME => LoginLink,
Order::OBJECT_NAME => Order,
OrderReturn::OBJECT_NAME => OrderReturn,
PaymentIntent::OBJECT_NAME => PaymentIntent,
Payout::OBJECT_NAME => Payout,
Person::OBJECT_NAME => Person,
Plan::OBJECT_NAME => Plan,
Product::OBJECT_NAME => Product,
Radar::ValueList::OBJECT_NAME => Radar::ValueList,
Radar::ValueListItem::OBJECT_NAME => Radar::ValueListItem,
Recipient::OBJECT_NAME => Recipient,
RecipientTransfer::OBJECT_NAME => RecipientTransfer,
Refund::OBJECT_NAME => Refund,
Reporting::ReportRun::OBJECT_NAME => Reporting::ReportRun,
Reporting::ReportType::OBJECT_NAME => Reporting::ReportType,
Reversal::OBJECT_NAME => Reversal,
Review::OBJECT_NAME => Review,
SKU::OBJECT_NAME => SKU,
Sigma::ScheduledQueryRun::OBJECT_NAME => Sigma::ScheduledQueryRun,
Source::OBJECT_NAME => Source,
SourceTransaction::OBJECT_NAME => SourceTransaction,
Subscription::OBJECT_NAME => Subscription,
SubscriptionItem::OBJECT_NAME => SubscriptionItem,
SubscriptionSchedule::OBJECT_NAME => SubscriptionSchedule,
SubscriptionScheduleRevision::OBJECT_NAME => SubscriptionScheduleRevision,
Terminal::ConnectionToken::OBJECT_NAME => Terminal::ConnectionToken,
Terminal::Location::OBJECT_NAME => Terminal::Location,
Terminal::Reader::OBJECT_NAME => Terminal::Reader,
ThreeDSecure::OBJECT_NAME => ThreeDSecure,
Token::OBJECT_NAME => Token,
Topup::OBJECT_NAME => Topup,
Transfer::OBJECT_NAME => Transfer,
UsageRecord::OBJECT_NAME => UsageRecord,
UsageRecordSummary::OBJECT_NAME => UsageRecordSummary,
WebhookEndpoint::OBJECT_NAME => WebhookEndpoint,
}
end

Expand Down
37 changes: 37 additions & 0 deletions test/stripe/subscription_schedule_revision_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

require ::File.expand_path("../../test_helper", __FILE__)

module Stripe
class SubscriptionScheduleRevisionTest < Test::Unit::TestCase
context "#resource_url" do
should "return a resource URL" do
revision = Stripe::SubscriptionScheduleRevision.construct_from(
id: "sub_sched_rev_123",
schedule: "sub_sched_123"
)
assert_equal "/v1/subscription_schedules/sub_sched_123/revisions/sub_sched_rev_123",
revision.resource_url
end

should "raise without a subscription schedule" do
revision = Stripe::SubscriptionScheduleRevision.construct_from(id: "sub_sched_rev_123")
assert_raises NotImplementedError do
revision.resource_url
end
end
end

should "raise on #retrieve" do
assert_raises NotImplementedError do
Stripe::SubscriptionScheduleRevision.retrieve("sub_sched_rev_123")
end
end

should "raise on #list" do
assert_raises NotImplementedError do
Stripe::SubscriptionScheduleRevision.list("sub_sched_rev_123", {})
end
end
end
end
35 changes: 35 additions & 0 deletions test/stripe/subscription_schedule_revisions_operations_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

require ::File.expand_path("../../test_helper", __FILE__)

module Stripe
class SubscriptionScheduleRevisionsOperationsTest < Test::Unit::TestCase
setup do
@schedule_id = "sub_sched_123"
@revision_id = "sub_sched_rev_123"
end

context "#retrieve_revision" do
should "retrieve a subscription schedule revision" do
revision = Stripe::SubscriptionSchedule.retrieve_revision(
@schedule_id,
@revision_id
)
assert_requested :get, "#{Stripe.api_base}/v1/subscription_schedules/#{@schedule_id}/revisions/#{@revision_id}"
assert revision.is_a?(Stripe::SubscriptionScheduleRevision)
end
end

context "#list_revisions" do
should "list a subscription schedule's revisions" do
revisions = Stripe::SubscriptionSchedule.list_revisions(
@schedule_id
)
assert_requested :get, "#{Stripe.api_base}/v1/subscription_schedules/#{@schedule_id}/revisions"
assert revisions.is_a?(Stripe::ListObject)
assert revisions.data.is_a?(Array)
assert revisions.data[0].is_a?(Stripe::SubscriptionScheduleRevision)
end
end
end
end
64 changes: 64 additions & 0 deletions test/stripe/subscription_schedule_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# frozen_string_literal: true

require ::File.expand_path("../../test_helper", __FILE__)

module Stripe
class SubscriptionScheduleTest < Test::Unit::TestCase
should "be listable" do
subscriptions = Stripe::SubscriptionSchedule.list
assert_requested :get, "#{Stripe.api_base}/v1/subscription_schedules"
assert subscriptions.data.is_a?(Array)
assert subscriptions.data[0].is_a?(Stripe::SubscriptionSchedule)
end

should "be retrievable" do
schedule = Stripe::SubscriptionSchedule.retrieve("sub_sched_123")
assert_requested :get,
"#{Stripe.api_base}/v1/subscription_schedules/sub_sched_123"
assert schedule.is_a?(Stripe::SubscriptionSchedule)
end

should "be creatable" do
schedule = Stripe::SubscriptionSchedule.create(
customer: "cus_123"
)
assert_requested :post, "#{Stripe.api_base}/v1/subscription_schedules"
assert schedule.is_a?(Stripe::SubscriptionSchedule)
end

should "be saveable" do
schedule = Stripe::SubscriptionSchedule.retrieve("sub_sched_123")
schedule.metadata["key"] = "value"
schedule.save
assert_requested :post,
"#{Stripe.api_base}/v1/subscription_schedules/#{schedule.id}"
end

should "be updateable" do
schedule = Stripe::SubscriptionSchedule.update("sub_sched_123", metadata: { foo: "bar" })
assert_requested :post,
"#{Stripe.api_base}/v1/subscription_schedules/sub_sched_123"
assert schedule.is_a?(Stripe::SubscriptionSchedule)
end

context "#cancel" do
should "cancel a subscription schedule" do
schedule = Stripe::SubscriptionSchedule.retrieve("sub_sched_123")
schedule = schedule.cancel
assert_requested :post,
"#{Stripe.api_base}/v1/subscription_schedules/#{schedule.id}/cancel"
assert schedule.is_a?(Stripe::SubscriptionSchedule)
end
end

context "#release" do
should "release a subscription schedule" do
schedule = Stripe::SubscriptionSchedule.retrieve("sub_sched_123")
schedule = schedule.release
assert_requested :post,
"#{Stripe.api_base}/v1/subscription_schedules/#{schedule.id}/release"
assert schedule.is_a?(Stripe::SubscriptionSchedule)
end
end
end
end
2 changes: 1 addition & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
require ::File.expand_path("../stripe_mock", __FILE__)

# If changing this number, please also change it in `.travis.yml`.
MOCK_MINIMUM_VERSION = "0.42.0".freeze
MOCK_MINIMUM_VERSION = "0.44.0".freeze
MOCK_PORT = Stripe::StripeMock.start

# Disable all real network connections except those that are outgoing to
Expand Down

0 comments on commit dd7a7fc

Please sign in to comment.