考慮@ VoteyDisciple的建議,我已經通過一些東西在RSpec中有合理的自動化(根據具體情況而定「合理」)。我使用VCR捕獲API調用(針對測試條帶環境),這是必不可少的,因爲這意味着sleep
調用僅在首次記錄測試時發生。
使用註釋來指示通過Stripe的API完成的行爲,因爲我的實現在我的項目中被困住了,而且沒那麼有用。
VCR.use_cassette('retry') do |cassette|
# Clear out existing Stripe data: customers, coupons, plans.
# This is so the test is reliably repeatable.
Stripe::Customer.all.each &:delete
Stripe::Coupon.all.each &:delete
Stripe::Plan.all.each &:delete
# Create a plan, in my case it has the id 'test'.
Stripe::Plan.create(
id: 'test',
amount: 100_00,
currency: 'AUD',
interval: 'month',
interval_count: 1,
name: 'RSpec Test'
)
# Create a customer
customer = Stripe::Customer.create email: '[email protected]'
token = card_token cassette, '4000000000000341'
# Add the card 4000000000000341 to the customer
customer.sources.create token: 'TOKEN for 0341'
# Create a subscription with a trial ending in two seconds.
subscription = customer.subscriptions.create(
plan: 'test',
trial_end: 2.seconds.from_now.to_i
)
# Wait for Stripe to create a proper invoice. I wish this
# was unavoidable, but I don't think it is.
sleep 180 if cassette.recording?
# Grab the invoice that actually has a dollar value.
# There's an invoice for the trial, and we don't care about that.
invoice = customer.invoices.detect { |invoice| invoice.total > 0 }
# Force Stripe to attempt payment for the first time (instead
# of waiting for hours).
begin
invoice.pay
rescue Stripe::CardError
# Expecting this to fail.
end
invoice.refresh
expect(invoice.paid).to eq(false)
expect(invoice.attempted).to eq(true)
# Add a new (valid) card to the customer.
token = card_token cassette, '4242424242424242'
card = customer.sources.create token: token
# and set it as the default
customer.default_source = card.id
customer.save
# Run the code in your app that retries the payment, which
# essentially invokes invoice.pay again.
# THIS IS FOR YOU TO IMPLEMENT
# And now we can check that the invoice wass successfully paid
invoice.refresh
expect(invoice.paid).to eq(true)
end
以自動化方式獲取卡令牌是一個全新的複雜領域。什麼我有可能不爲別人打工,但這裏的紅寶石方法,呼喚phantomjs(你需要通過發送VCR中的對象):
def card_token(cassette, card = '4242424242424242')
return 'tok_my_default_test_token' unless cassette.recording?
token = `phantomjs --ignore-ssl-errors=true --ssl-protocol=any ./spec/fixtures/stripe_tokens.js #{ENV['STRIPE_PUBLISH_KEY']} #{card}`.strip
raise "Unexpected token: #{token}" unless token[/^tok_/]
token
end
這phantomjs運行JavaScript文件(stripe_tokens.js)包含:
var page = require('webpage').create(),
system = require('system');
var key = system.args[1],
card = system.args[2];
page.onCallback = function(data) {
console.log(data);
phantom.exit();
};
page.open('spec/fixtures/stripe_tokens.html', function(status) {
if (status == 'success') {
page.evaluate(function(key, card) {
Stripe.setPublishableKey(key);
Stripe.card.createToken(
{number: card, cvc: "123", exp_month: "12", exp_year: "2019"},
function(status, response) { window.callPhantom(response.id) }
);
}, key, card);
}
});
最後,所涉及的HTML文件(stripe_tokens.html)很簡單:
<html>
<head>
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
</head>
<body></body>
</html>
把所有的一起,並很好,它可能工作!它爲我們的應用程序:)
我害怕這一點。 –
我遇到了同樣的問題,但對於第2步/ 3,以編程方式更新訂閱上的'trial_end'屬性。以編程方式進行,意味着您可以根據自己的喜好給出一個結束時間,例如, <1分鐘。像郵差這樣的東西使這非常容易。 – Bede