- 更新日: 2015年7月8日
- Rails
WebPayテスト環境のオブジェクトを削除するRakeタスク
Rails プロジェクトで WebPay を使ったクレジットカード決済の RSpec テストコードを書いていたのですが、昨日まで通っていたテストがこけまくるエラーにいきなり遭遇して立ち往生しました。
WebPay で顧客に対して定期課金を行う処理のためのテストコードだったのですけど、原因を解明するのに苦労してしまった…。WebPay のテスト環境での話です。webpay 3.2.2(WebPay の ruby 用 gem)を使用しています。
— 環境 —
rails 4.1
rake 10.4.2
webpay 3.2.2
WebPay テスト環境ではオブジェクト(インスタンス)の上限数が300
Ruby 用 API のドキュメントは以下。WebPay の API 自体はとても分かりやすくて使いやすいです。
Ruby APIドキュメント | WebPay: 開発者向けクレジットカード決済サービス
上記 Ruby API ドキュメントを読むと分かるのですが、WebPay の決済フローでは以下のオブジェクト等が登場します。
・課金(Charges)
・顧客(Customers)
・トークン(Tokens)
・定期課金(Recursions)
・イベント(Events)
・アカウント(Account)
結論から言いますと、いきなりテストがこけまくるようになった原因は、WebPay テスト環境での顧客オブジェクト数が上限の300個に達していたためでした。RSpec テスト実行で、いつのまにか顧客オブジェクトが上限の300まで作られてしまっていた。調べまくって、ようやくテスト環境でのオブジェクト上限数に関する以下ページを見つけました。
テスト環境で作成できるインスタンスの上限数が300になりました – WebPay Engineering Blog
利用料金 | WebPay: 開発者向けクレジットカード決済サービス
WebPay のテスト環境ですと、各々オブジェクトの数の上限が300に定められているようです。テスト環境の管理画面で顧客数がぴったり300になっていたのに気付いて、もしかして…と「webpay 300」でググったところ、上記ページを発見した次第です。これ初見ですと超気付きにくいと思う…
WebPay::ErrorResponse::ErrorResponseError の例外を捕捉するとエラー原因の詳細が分かるそうなのですが、e.data.error.caused_by が ‘insufficient’(# 実装ミスに起因する)を返して、ずっと実装側のミスだと思い込んでたのもはまった一因。
ということで、試しに管理画面から300に到達していた顧客オブジェクトをいくつか削除したところ、無事にテストが通るようになりました。ちなみに、顧客オブジェクトに定期課金が紐付いている場合は、先に定期課金オブジェクトを削除しないと、顧客オブジェクトを削除できません。
指定した日付以降に作成された顧客オブジェクトを削除する Rake タスク
WebPay 管理画面からちまちま1件ずつ、WebPay オブジェクトを削除しても良いのですが面倒くさい。なので、指定した日付以降の分を一気に削除する Rake タスクを書きました。以下、顧客オブジェクトを紐付けられた定期課金オブジェクトとともに削除する Rake タスクです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
namespace :webpay do # usage => $ bundle exec rake "webpay:delete_customers_with_recursions[2015, 7, 8]" desc "delete customers with recursions after designated date" task :delete_customers_with_recursions, ['year', 'month', 'day'] => :environment do |task, args| next unless Rails.env.development? || Rails.env.test? webpay = WebPay.new("********") # webpay secret key utc_timestamp = Time.utc(args.year.to_i, args.month.to_i, args.day.to_i).beginning_of_day.to_i customers = webpay.customer.all(count: 100, created: {gte: utc_timestamp} ) customers.data.each do |cus| puts cus.id cus.recursions.each do |rec| puts rec.id webpay.recursion.delete(id: rec.id) end webpay.customer.delete(id: cus.id) end end end |
webpay.customer.all の WebPay API で取得できる数が最大で100件(count: 100)なので、100件以上削除したい場合は2回以上 rake タスクを実行する必要がある。count を指定しないと、デフォルトでは10件取得です。
また webpay.customer.all で、created: {gte: utc_timestamp} とオプションを指定することで greater than or equal to(gte)なデータ(指定したUTCタイムスタンプ以降のデータ)を取得できます。
あとは取得した顧客(customers)を each で回して、顧客(cus)に紐付けられた定期課金(cus.recursions)を先に削除して、その後に顧客(cus)を削除。雑なコードで色々ブラッシュアップが必要ですが、一応以上の Rake タスク処理で、指定日付以降の顧客オブジェクトをいっぺんに削除できました。
残る課題としては、RSpec テストコード中で作成した WebPay オブジェクトを、テスト実行後に自動で削除できるようにする処理の追加もしないといけません。テスト中で作成した WebPay オブジェクトを削除できるようにする RSpec ヘルパーか Rake タスクを書いて、それを RSpec の after do ~ end の中で呼ぶようにすれば良いかな。
- Rails の関連記事
- RailsでMySQLパーティショニングのマイグレーション
- Rails ActiveRecordでdatetime型カラムのGROUP BY集計にタイムゾーンを考慮する
- RailsプラグインGemの作成方法、RSpecテストまで含めたrails pluginの作り方
- RailsでAMPに対応するgemをリリースしました
- Railsでrequest.urlとrequest.original_urlの違い
- Railsでwheneverによるcronバッチ処理
- Google AnalyticsのRails Turbolinks対応
- Railsアプリにソーシャル・シェアボタンを簡単設置
- Rails監視ツール用にErrbitをHerokuで運用
- Facebook APIバージョンのアップグレード手順(Rails OmniAuth)
Leave Your Message!