payjp 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rubocop.yml +82 -0
  4. data/.rubocop_todo.yml +35 -0
  5. data/.travis.yml +22 -0
  6. data/CONTRIBUTORS +0 -0
  7. data/Gemfile +8 -0
  8. data/History.txt +0 -0
  9. data/LICENSE +21 -0
  10. data/README.rdoc +43 -0
  11. data/Rakefile +8 -0
  12. data/VERSION +1 -0
  13. data/gemfiles/default-with-activesupport.gemfile +10 -0
  14. data/gemfiles/json.gemfile +12 -0
  15. data/gemfiles/yajl.gemfile +12 -0
  16. data/lib/payjp.rb +279 -0
  17. data/lib/payjp/account.rb +11 -0
  18. data/lib/payjp/api_operations/create.rb +16 -0
  19. data/lib/payjp/api_operations/delete.rb +11 -0
  20. data/lib/payjp/api_operations/list.rb +17 -0
  21. data/lib/payjp/api_operations/request.rb +39 -0
  22. data/lib/payjp/api_operations/update.rb +17 -0
  23. data/lib/payjp/api_resource.rb +35 -0
  24. data/lib/payjp/card.rb +18 -0
  25. data/lib/payjp/charge.rb +27 -0
  26. data/lib/payjp/customer.rb +8 -0
  27. data/lib/payjp/errors/api_connection_error.rb +4 -0
  28. data/lib/payjp/errors/api_error.rb +4 -0
  29. data/lib/payjp/errors/authentication_error.rb +4 -0
  30. data/lib/payjp/errors/card_error.rb +11 -0
  31. data/lib/payjp/errors/invalid_request_error.rb +10 -0
  32. data/lib/payjp/errors/payjp_error.rb +20 -0
  33. data/lib/payjp/event.rb +5 -0
  34. data/lib/payjp/list_object.rb +33 -0
  35. data/lib/payjp/payjp_object.rb +259 -0
  36. data/lib/payjp/plan.rb +8 -0
  37. data/lib/payjp/subscription.rb +37 -0
  38. data/lib/payjp/token.rb +5 -0
  39. data/lib/payjp/transfer.rb +5 -0
  40. data/lib/payjp/util.rb +121 -0
  41. data/lib/payjp/version.rb +3 -0
  42. data/payjp.gemspec +27 -0
  43. data/test/payjp/account_test.rb +17 -0
  44. data/test/payjp/api_resource_test.rb +445 -0
  45. data/test/payjp/charge_test.rb +83 -0
  46. data/test/payjp/customer_card_test.rb +61 -0
  47. data/test/payjp/customer_test.rb +35 -0
  48. data/test/payjp/event_test.rb +26 -0
  49. data/test/payjp/list_object_test.rb +16 -0
  50. data/test/payjp/metadata_test.rb +103 -0
  51. data/test/payjp/payjp_object_test.rb +28 -0
  52. data/test/payjp/plan_test.rb +48 -0
  53. data/test/payjp/subscription_test.rb +58 -0
  54. data/test/payjp/token_test.rb +34 -0
  55. data/test/payjp/transfer_test.rb +34 -0
  56. data/test/payjp/util_test.rb +34 -0
  57. data/test/test_data.rb +291 -0
  58. data/test/test_helper.rb +45 -0
  59. metadata +201 -0
@@ -0,0 +1,83 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Payjp
4
+ class ChargeTest < Test::Unit::TestCase
5
+ should "charges should be listable" do
6
+ @mock.expects(:get).once.returns(test_response(test_charge_array))
7
+ c = Payjp::Charge.all
8
+ assert c.data.is_a? Array
9
+ c.each do |charge|
10
+ assert charge.is_a?(Payjp::Charge)
11
+ end
12
+ end
13
+
14
+ should "charges should be refundable" do
15
+ @mock.expects(:get).never
16
+ @mock.expects(:post).once.returns(test_response({ :id => "ch_test_charge", :refunded => true }))
17
+ c = Payjp::Charge.new("test_charge")
18
+ c.refund
19
+ assert c.refunded
20
+ end
21
+
22
+ should "charges should not be deletable" do
23
+ assert_raises NoMethodError do
24
+ @mock.expects(:get).once.returns(test_response(test_charge))
25
+ c = Payjp::Charge.retrieve("test_charge")
26
+ c.delete
27
+ end
28
+ end
29
+
30
+ should "charges should be updateable" do
31
+ @mock.expects(:get).once.returns(test_response(test_charge))
32
+ @mock.expects(:post).once.returns(test_response(test_charge))
33
+ c = Payjp::Charge.new("test_charge")
34
+ c.refresh
35
+ c.mnemonic = "New charge description"
36
+ c.save
37
+ end
38
+
39
+ should "charges should have Card objects associated with their Card property" do
40
+ @mock.expects(:get).once.returns(test_response(test_charge))
41
+ c = Payjp::Charge.retrieve("test_charge")
42
+ assert c.card.is_a?(Payjp::PayjpObject) && c.card.object == 'card'
43
+ end
44
+
45
+ should "execute should return a new, fully executed charge when passed correct `card` parameters" do
46
+ @mock.expects(:post).with do |url, api_key, params|
47
+ url == "#{Payjp.api_base}/v1/charges" && api_key.nil? && CGI.parse(params) == {
48
+ 'currency' => ['jpy'], 'amount' => ['100'],
49
+ 'card[exp_year]' => ['2012'],
50
+ 'card[number]' => ['4242424242424242'],
51
+ 'card[exp_month]' => ['11']
52
+ }
53
+ end.once.returns(test_response(test_charge))
54
+
55
+ c = Payjp::Charge.create({
56
+ :amount => 100,
57
+ :card => {
58
+ :number => "4242424242424242",
59
+ :exp_month => 11,
60
+ :exp_year => 2012
61
+ },
62
+ :currency => "jpy"
63
+ })
64
+ assert c.paid
65
+ end
66
+
67
+ should "execute should return a new, fully executed charge when passed correct `source` parameters" do
68
+ @mock.expects(:post).with do |url, api_key, params|
69
+ url == "#{Payjp.api_base}/v1/charges" && api_key.nil? && CGI.parse(params) == {
70
+ 'currency' => ['jpy'], 'amount' => ['100'],
71
+ 'source' => ['btcrcv_test_receiver']
72
+ }
73
+ end.once.returns(test_response(test_charge))
74
+
75
+ c = Payjp::Charge.create({
76
+ :amount => 100,
77
+ :source => 'btcrcv_test_receiver',
78
+ :currency => "jpy"
79
+ })
80
+ assert c.paid
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+ module Payjp
3
+ class CustomerCardTest < Test::Unit::TestCase
4
+ CUSTOMER_CARD_URL = '/v1/customers/test_customer/cards/test_card'
5
+
6
+ def customer
7
+ @mock.expects(:get).once.returns(test_response(test_customer))
8
+ Payjp::Customer.retrieve('test_customer')
9
+ end
10
+
11
+ should "customer cards should be listable" do
12
+ c = customer
13
+ @mock.expects(:get).once.returns(test_response(test_customer_card_array(customer.id)))
14
+ cards = c.cards.all(:object => "card").data
15
+ assert cards.is_a? Array
16
+ assert cards[0].is_a? Payjp::Card
17
+ end
18
+
19
+ should "customer cards should have the correct url" do
20
+ c = customer
21
+ @mock.expects(:get).once.returns(test_response(test_card(
22
+ :id => 'test_card'
23
+ )))
24
+ card = c.cards.retrieve('card')
25
+ assert_equal CUSTOMER_CARD_URL, card.url
26
+ end
27
+
28
+ should "customer cards should be deletable" do
29
+ c = customer
30
+ @mock.expects(:get).once.returns(test_response(test_card))
31
+ @mock.expects(:delete).once.returns(test_response(test_card(:deleted => true)))
32
+ card = c.cards.retrieve('card')
33
+ card.delete
34
+ assert card.deleted
35
+ end
36
+
37
+ should "customer cards should be updateable" do
38
+ c = customer
39
+ @mock.expects(:get).once.returns(test_response(test_card(:exp_year => "2000")))
40
+ @mock.expects(:post).once.returns(test_response(test_card(:exp_year => "2100")))
41
+ card = c.cards.retrieve('card')
42
+ assert_equal "2000", card.exp_year
43
+ card.exp_year = "2100"
44
+ card.save
45
+ assert_equal "2100", card.exp_year
46
+ end
47
+
48
+ should "create should return a new customer card" do
49
+ c = customer
50
+ @mock.expects(:post).once.returns(test_response(test_card(:id => "test_card")))
51
+ card = c.cards.create(:source => "tok_41YJ05ijAaWaFS")
52
+ assert_equal "test_card", card.id
53
+ end
54
+
55
+ should "raise if accessing Payjp::Card.retrieve directly" do
56
+ assert_raises NotImplementedError do
57
+ Payjp::Card.retrieve "card_12345"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Payjp
4
+ class CustomerTest < Test::Unit::TestCase
5
+ should "customers should be listable" do
6
+ @mock.expects(:get).once.returns(test_response(test_customer_array))
7
+ c = Payjp::Customer.all.data
8
+ assert c.is_a? Array
9
+ assert c[0].is_a? Payjp::Customer
10
+ end
11
+
12
+ should "customers should be deletable" do
13
+ @mock.expects(:delete).once.returns(test_response(test_customer({ :deleted => true })))
14
+ c = Payjp::Customer.new("test_customer")
15
+ c.delete
16
+ assert c.deleted
17
+ end
18
+
19
+ should "customers should be updateable" do
20
+ @mock.expects(:get).once.returns(test_response(test_customer({ :mnemonic => "foo" })))
21
+ @mock.expects(:post).once.returns(test_response(test_customer({ :mnemonic => "bar" })))
22
+ c = Payjp::Customer.new("test_customer").refresh
23
+ assert_equal "foo", c.mnemonic
24
+ c.mnemonic = "bar"
25
+ c.save
26
+ assert_equal "bar", c.mnemonic
27
+ end
28
+
29
+ should "create should return a new customer" do
30
+ @mock.expects(:post).once.returns(test_response(test_customer))
31
+ c = Payjp::Customer.create
32
+ assert_equal "c_test_customer", c.id
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Payjp
4
+ class EventTest < Test::Unit::TestCase
5
+ should "events should be listable" do
6
+ @mock.expects(:get).once.returns(test_response(test_event_array))
7
+ c = Payjp::Event.all.data
8
+ assert c.is_a? Array
9
+ assert c[0].is_a? Payjp::Event
10
+ end
11
+
12
+ should "retrieve should retrieve event" do
13
+ @mock.expects(:get).once.returns(test_response(test_event))
14
+ event = Payjp::Event.retrieve('tr_test_event')
15
+ assert_equal 'evnt_test_event', event.id
16
+ end
17
+
18
+ should "events should not be deletable" do
19
+ assert_raises NoMethodError do
20
+ @mock.expects(:get).once.returns(test_response(test_event))
21
+ event = Payjp::Event.retrieve('evnt_test_event')
22
+ event.delete
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Payjp
4
+ class ListObjectTest < Test::Unit::TestCase
5
+ should "be able to retrieve full lists given a listobject" do
6
+ @mock.expects(:get).twice.returns(test_response(test_charge_array))
7
+ c = Payjp::Charge.all
8
+ assert c.is_a?(Payjp::ListObject)
9
+ assert_equal('/v1/charges', c.url)
10
+ all = c.all
11
+ assert all.is_a?(Payjp::ListObject)
12
+ assert_equal('/v1/charges', all.url)
13
+ assert all.data.is_a?(Array)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,103 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Payjp
4
+ class MetadataTest < Test::Unit::TestCase
5
+ setup do
6
+ @metadata_supported = {
7
+ :charge => {
8
+ :new => Payjp::Charge.method(:new),
9
+ :test => method(:test_charge),
10
+ :url => "/v1/charges/#{test_charge[:id]}"
11
+ },
12
+ :customer => {
13
+ :new => Payjp::Customer.method(:new),
14
+ :test => method(:test_customer),
15
+ :url => "/v1/customers/#{test_customer[:id]}"
16
+ }
17
+ }
18
+
19
+ @base_url = "#{Payjp.api_base}"
20
+ end
21
+
22
+ should "not touch metadata" do
23
+ update_actions = lambda { |obj| obj.description = 'test' }
24
+ check_metadata({ :metadata => { 'initial' => 'true' } },
25
+ 'description=test',
26
+ update_actions)
27
+ end
28
+
29
+ should "update metadata as a whole" do
30
+ update_actions = lambda { |obj| obj.metadata = { 'uuid' => '6735' } }
31
+ check_metadata({ :metadata => {} },
32
+ 'metadata[uuid]=6735',
33
+ update_actions)
34
+
35
+ if greater_than_ruby_1_9?
36
+ check_metadata({ :metadata => { :initial => 'true' } },
37
+ 'metadata[uuid]=6735&metadata[initial]=',
38
+ update_actions)
39
+ end
40
+ end
41
+
42
+ should "update metadata keys individually" do
43
+ update_actions = lambda { |obj| obj.metadata['txn_id'] = '134a13' }
44
+ check_metadata({ :metadata => { 'initial' => 'true' } },
45
+ 'metadata[txn_id]=134a13',
46
+ update_actions)
47
+ end
48
+
49
+ should "clear metadata as a whole" do
50
+ update_actions = lambda { |obj| obj.metadata = nil }
51
+ check_metadata({ :metadata => { 'initial' => 'true' } },
52
+ 'metadata=',
53
+ update_actions)
54
+ end
55
+
56
+ should "clear metadata keys individually" do
57
+ update_actions = lambda { |obj| obj.metadata['initial'] = nil }
58
+ check_metadata({ :metadata => { 'initial' => 'true' } },
59
+ 'metadata[initial]=',
60
+ update_actions)
61
+ end
62
+
63
+ should "handle combinations of whole and partial metadata updates" do
64
+ if greater_than_ruby_1_9?
65
+ update_actions = lambda do |obj|
66
+ obj.metadata = { 'type' => 'summer' }
67
+ obj.metadata['uuid'] = '6735'
68
+ end
69
+ params = { :metadata => { 'type' => 'summer', 'uuid' => '6735' } }
70
+ curl_args = Payjp.uri_encode(params)
71
+ check_metadata({ :metadata => { 'type' => 'christmas' } },
72
+ curl_args,
73
+ update_actions)
74
+ end
75
+ end
76
+
77
+ def check_metadata(initial_params, curl_args, metadata_update)
78
+ @metadata_supported.each do |_name, methods|
79
+ neu = methods[:new]
80
+ test = methods[:test]
81
+ url = @base_url + methods[:url]
82
+
83
+ initial_test_obj = test.call(initial_params)
84
+ @mock.expects(:get).once.returns(test_response(initial_test_obj))
85
+
86
+ final_test_obj = test.call
87
+ @mock.expects(:post).once.
88
+ returns(test_response(final_test_obj)).
89
+ with(url, nil, curl_args)
90
+
91
+ obj = neu.call("test")
92
+ obj.refresh
93
+ metadata_update.call(obj)
94
+ obj.save
95
+ end
96
+ end
97
+
98
+ def greater_than_ruby_1_9?
99
+ version = RUBY_VERSION.dup # clone preserves frozen state
100
+ Gem::Version.new(version) >= Gem::Version.new('1.9')
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Payjp
4
+ class PayjpObjectTest < Test::Unit::TestCase
5
+ should "implement #respond_to correctly" do
6
+ obj = Payjp::PayjpObject.construct_from({ :id => 1, :foo => 'bar' })
7
+ assert obj.respond_to?(:id)
8
+ assert obj.respond_to?(:foo)
9
+ assert !obj.respond_to?(:baz)
10
+ end
11
+
12
+ should "marshal a payjp object correctly" do
13
+ obj = Payjp::PayjpObject.construct_from({ :id => 1, :name => 'Payjp' }, { :api_key => 'apikey' })
14
+ m = Marshal.load(Marshal.dump(obj))
15
+ assert_equal 1, m.id
16
+ assert_equal 'Payjp', m.name
17
+ expected_hash = { :api_key => 'apikey' }
18
+ assert_equal expected_hash, m.instance_variable_get('@opts')
19
+ end
20
+
21
+ should "recursively call to_hash on its values" do
22
+ nested = Payjp::PayjpObject.construct_from({ :id => 7, :foo => 'bar' })
23
+ obj = Payjp::PayjpObject.construct_from({ :id => 1, :nested => nested })
24
+ expected_hash = { :id => 1, :nested => { :id => 7, :foo => 'bar' } }
25
+ assert_equal expected_hash, obj.to_hash
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,48 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Payjp
4
+ class PlanTest < Test::Unit::TestCase
5
+ should "create should return a new plan" do
6
+ @mock.expects(:post).once.returns(test_response(test_plan))
7
+ plan = Payjp::Plan.create({
8
+ :amount => 500,
9
+ :currency => 'jpy',
10
+ :interval => 'month',
11
+ :trial_days => 30
12
+ })
13
+ assert_equal 'pln_test_plan', plan.id
14
+ end
15
+
16
+ should "retrieve should retrieve plan" do
17
+ @mock.expects(:get).once.returns(test_response(test_plan))
18
+ plan = Payjp::Plan.retrieve('pln_test_plan')
19
+ assert_equal 'pln_test_plan', plan.id
20
+ end
21
+
22
+ should "plans should be deletable" do
23
+ @mock.expects(:delete).once.returns(test_response(test_plan({ :deleted => true })))
24
+ plan = Payjp::Plan.new("test_plan")
25
+ plan.delete
26
+ assert plan.deleted
27
+ end
28
+
29
+ should "plans should be listable" do
30
+ @mock.expects(:get).once.returns(test_response(test_plan_array))
31
+ plans = Payjp::Plan.all
32
+ assert plans.data.is_a? Array
33
+ plans.each do |plan|
34
+ assert plan.is_a?(Payjp::Plan)
35
+ end
36
+ end
37
+
38
+ should "plans should be updateable" do
39
+ @mock.expects(:get).once.returns(test_response(test_plan({ :name => 'current plan' })))
40
+ @mock.expects(:post).once.returns(test_response(test_plan({ :name => 'new plan' })))
41
+ plan = Payjp::Plan.new("test_plan").refresh
42
+ assert_equal 'current plan', plan.name
43
+ plan.name = 'new plan'
44
+ plan.save
45
+ assert_equal 'new plan', plan.name
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Payjp
4
+ class SubscriptionTest < Test::Unit::TestCase
5
+ should "subscriptions should be listable" do
6
+ @mock.expects(:get).once.returns(test_response(test_customer))
7
+
8
+ customer = Payjp::Customer.retrieve('test_customer')
9
+
10
+ assert customer.subscriptions.first.is_a?(Payjp::Subscription)
11
+ end
12
+
13
+ should "subscriptions should be refreshable" do
14
+ @mock.expects(:get).twice.returns(test_response(test_customer), test_response(test_subscription(:id => 'refreshed_subscription')))
15
+
16
+ customer = Payjp::Customer.retrieve('test_customer')
17
+ subscription = customer.subscriptions.first
18
+ subscription.refresh
19
+
20
+ assert_equal 'refreshed_subscription', subscription.id
21
+ end
22
+
23
+ should "subscriptions should be deletable" do
24
+ @mock.expects(:get).once.returns(test_response(test_customer))
25
+ customer = Payjp::Customer.retrieve('test_customer')
26
+ subscription = customer.subscriptions.first
27
+
28
+ @mock.expects(:delete).once.with("#{Payjp.api_base}/v1/subscriptions/#{subscription.id}?at_period_end=true", nil, nil).returns(test_response(test_subscription))
29
+ subscription.delete :at_period_end => true
30
+
31
+ @mock.expects(:delete).once.with("#{Payjp.api_base}/v1/subscriptions/#{subscription.id}", nil, nil).returns(test_response(test_subscription))
32
+ subscription.delete
33
+ end
34
+
35
+ should "subscriptions should be updateable" do
36
+ @mock.expects(:get).once.returns(test_response(test_customer))
37
+ @mock.expects(:post).once.returns(test_response(test_subscription({ :status => 'active' })))
38
+
39
+ customer = Payjp::Customer.retrieve('test_customer')
40
+ subscription = customer.subscriptions.first
41
+ assert_equal 'trialing', subscription.status
42
+
43
+ subscription.status = 'active'
44
+ subscription.save
45
+
46
+ assert_equal 'active', subscription.status
47
+ end
48
+
49
+ should "create should return a new subscription" do
50
+ @mock.expects(:get).once.returns(test_response(test_customer))
51
+ @mock.expects(:post).once.returns(test_response(test_subscription(:id => 'test_new_subscription')))
52
+
53
+ customer = Payjp::Customer.retrieve('test_customer')
54
+ subscription = customer.subscriptions.create(:plan => 'silver')
55
+ assert_equal 'test_new_subscription', subscription.id
56
+ end
57
+ end
58
+ end