recurly 0.4.11 → 0.4.13

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of recurly might be problematic. Click here for more details.

Files changed (70) hide show
  1. data/README.md +4 -8
  2. data/lib/recurly.rb +10 -19
  3. data/lib/recurly/config_parser.rb +5 -2
  4. data/lib/recurly/plan.rb +0 -1
  5. data/lib/recurly/rails3/recurly.rake +10 -26
  6. data/lib/recurly/transparent.rb +2 -0
  7. data/lib/recurly/verification.rb +14 -8
  8. data/lib/recurly/version.rb +1 -1
  9. data/spec/config/recurly.yml +3 -3
  10. data/spec/config/test1.yml +1 -3
  11. data/spec/config/test2.yml +2 -6
  12. data/spec/unit/config_spec.rb +9 -16
  13. data/spec/unit/transparent_spec.rb +0 -20
  14. data/spec/unit/verification_spec.rb +15 -9
  15. data/spec/vcr/account/accept-language-account/1313708721.yml +52 -31
  16. data/spec/vcr/account/close/1313708721.yml +107 -79
  17. data/spec/vcr/account/create-blank/1313708721.yml +37 -26
  18. data/spec/vcr/account/create-duplicate/1313708721.yml +83 -54
  19. data/spec/vcr/account/create-min/1313708721.yml +48 -30
  20. data/spec/vcr/account/create/1313708721.yml +52 -31
  21. data/spec/vcr/account/find/1313708721.yml +111 -81
  22. data/spec/vcr/account/list/1313708721.yml +1148 -719
  23. data/spec/vcr/account/update/1313708721.yml +182 -124
  24. data/spec/vcr/billing/create/1313708721.yml +156 -93
  25. data/spec/vcr/billing/destroy/1313708721.yml +198 -135
  26. data/spec/vcr/billing/errors/1313708721.yml +91 -56
  27. data/spec/vcr/billing/find/1313708721.yml +200 -122
  28. data/spec/vcr/billing/update/1313708721.yml +218 -126
  29. data/spec/vcr/charge/create/1313708721.yml +189 -120
  30. data/spec/vcr/charge/delete-uninvoiced/1313708721.yml +195 -154
  31. data/spec/vcr/charge/list-all/1313708721.yml +235 -157
  32. data/spec/vcr/charge/list-invoiced/1313708721.yml +351 -234
  33. data/spec/vcr/charge/list-pending/1313708721.yml +235 -159
  34. data/spec/vcr/charge/lookup/1313708721.yml +127 -87
  35. data/spec/vcr/coupon/create/1296774903.yml +83 -95
  36. data/spec/vcr/coupon/destroy/1296774903.yml +81 -115
  37. data/spec/vcr/credit/create/1313708090.yml +127 -87
  38. data/spec/vcr/credit/delete/1313708090.yml +169 -129
  39. data/spec/vcr/credit/list/1313708090.yml +235 -157
  40. data/spec/vcr/credit/lookup/1313708090.yml +127 -87
  41. data/spec/vcr/invoice/create-no-charges/1296674173.yml +140 -89
  42. data/spec/vcr/invoice/create/1296674173.yml +259 -162
  43. data/spec/vcr/invoice/list/1296674173.yml +342 -227
  44. data/spec/vcr/invoice/lookup/1296674173.yml +260 -167
  45. data/spec/vcr/plan/all.yml +206 -198
  46. data/spec/vcr/plan/find.yml +109 -103
  47. data/spec/vcr/plan/update.yml +126 -93
  48. data/spec/vcr/subscription/addons/add/1296674173.yml +156 -261
  49. data/spec/vcr/subscription/addons/create/1296674173.yml +156 -164
  50. data/spec/vcr/subscription/addons/remove/1296674173.yml +156 -249
  51. data/spec/vcr/subscription/cancel-with-code/1296674173.yml +340 -243
  52. data/spec/vcr/subscription/cancel/1296674173.yml +297 -210
  53. data/spec/vcr/subscription/change1/1296674173.yml +303 -213
  54. data/spec/vcr/subscription/change2/1296674173.yml +303 -214
  55. data/spec/vcr/subscription/create/1296674173.yml +167 -111
  56. data/spec/vcr/subscription/find/1296674173.yml +210 -145
  57. data/spec/vcr/subscription/reactivate/1296674173.yml +318 -233
  58. data/spec/vcr/subscription/refund-full/1296674173.yml +277 -199
  59. data/spec/vcr/subscription/refund-none/1296674173.yml +277 -199
  60. data/spec/vcr/subscription/refund-partial/1296674173.yml +277 -199
  61. data/spec/vcr/transaction/all/1311126815.yml +388 -206
  62. data/spec/vcr/transaction/create-no-account/1311126815.yml +74 -43
  63. data/spec/vcr/transaction/create-with-account/1311126815.yml +172 -101
  64. data/spec/vcr/transaction/list-filled/1311126815.yml +486 -291
  65. data/spec/vcr/transaction/list-initial/1311126815.yml +159 -98
  66. data/spec/vcr/transaction/lookup/1311126815.yml +420 -268
  67. data/spec/vcr/transaction/void/1311126815.yml +280 -174
  68. metadata +109 -77
  69. data/spec/vcr/transaction/refund/1311126815.yml +0 -163
  70. data/spec/vcr/transparent/post-url/1311239470.yml +0 -76
data/README.md CHANGED
@@ -16,7 +16,7 @@ Installation
16
16
 
17
17
  **Stable Version:**
18
18
 
19
- gem 'recurly'
19
+ gem 'recurly', '~> 0.4.11'
20
20
 
21
21
  **Bleeding Edge Version:**
22
22
 
@@ -37,10 +37,8 @@ Setup (Rails 2 and other frameworks)
37
37
  Alternatively, if not using Rails 3, just make sure to call a Recurly configure block somewhere in your applications initialization.
38
38
 
39
39
  Recurly.configure do |c|
40
- c.username = 'api@yourcompany.com'
41
- c.password = 'your_api_key'
40
+ c.api_key = 'your_api_key'
42
41
  c.private_key = 'your_private_key'
43
- c.environment = :production # or :sandbox for test sites
44
42
  c.subdomain = 'your-recurly-subdomain'
45
43
  end
46
44
 
@@ -48,7 +46,7 @@ In Rails 2.x, this code should be in config/initializers/recurly.rb
48
46
 
49
47
  In Sinatra, it should be within a `configure` block.
50
48
 
51
- **Please Note:** the setup parameters changed in version 0.4.0. The Ruby client now connects to either api-production.recurly.com or api-sandbox.recurly.com to improve DNS lookups. Additional configuration options were also added for the [Transparent Post API](http://docs.recurly.com/transparent-post/basics).
49
+ **Please Note:** the setup parameters changed in version 0.4.0. Additional configuration options were also added for the [Transparent Post API](http://docs.recurly.com/transparent-post/basics).
52
50
 
53
51
  Manual Setup via YAML or JSON
54
52
  --------------
@@ -58,10 +56,8 @@ You can also configure Recurly via a YAML file by using:
58
56
 
59
57
  The Recurly Configuration YAML is in the format of:
60
58
 
61
- username: myrecurlyuser@domain.com
62
- password: your_api_key
59
+ api_key: your_api_key
63
60
  private_key: your_private_key
64
- environment: :production
65
61
  subdomain: your_recurly_subdomain
66
62
 
67
63
 
@@ -41,7 +41,7 @@ module Recurly
41
41
  autoload :Verification, 'recurly/verification'
42
42
 
43
43
  class << self
44
- attr_accessor :username, :password, :environment, :subdomain, :private_key
44
+ attr_accessor :api_key, :environment, :subdomain, :private_key
45
45
 
46
46
  # default Recurly.settings_path to config/recurly.yml
47
47
  unless respond_to?(:settings_path)
@@ -55,15 +55,14 @@ module Recurly
55
55
  end
56
56
 
57
57
  def configured?
58
- Base.user && Base.password && Base.site
58
+ Base.user && Base.site
59
59
  end
60
60
 
61
61
  def configure
62
62
  if block_given?
63
63
  yield self
64
64
 
65
- Base.user = username
66
- Base.password = password
65
+ Base.user = api_key
67
66
  Base.site = site_for_environment(environment)
68
67
 
69
68
  return true
@@ -77,22 +76,16 @@ module Recurly
77
76
  end
78
77
 
79
78
  def site_for_environment(environment)
80
- environment = :production if environment.nil? # Default to production
81
- case environment.to_sym
82
- when :development
83
- "http://app.lvh.me:3000"
84
- when :production
85
- "https://api-production.recurly.com"
86
- when :sandbox
87
- "https://api-sandbox.recurly.com"
79
+ if environment == :development
80
+ "http://api.lvh.me:3000"
88
81
  else
89
- raise Recurly::ConfigurationError.new("Invalid environment (#{environment}). Valid values are: :production, :sandbox.")
82
+ "https://api.recurly.com"
90
83
  end
91
84
  end
92
85
 
93
86
 
94
87
  # allows configuration from a yml file that contains the fields:
95
- # username,password,site,private_key
88
+ # api_key,site,private_key
96
89
  def configure_from_yaml(path = nil)
97
90
  configure do |c|
98
91
  # parse configuration from yml
@@ -105,8 +98,7 @@ module Recurly
105
98
  recurly_env ||= ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
106
99
  recurly_config = recurly_config[recurly_env] if recurly_config.has_key?(recurly_env)
107
100
 
108
- c.username = recurly_config["username"]
109
- c.password = recurly_config["password"]
101
+ c.api_key = recurly_config["api_key"] || recurly_config["password"]
110
102
  c.subdomain = recurly_config["subdomain"]
111
103
  c.private_key = recurly_config["private_key"]
112
104
  c.environment = recurly_config["environment"]
@@ -115,12 +107,11 @@ module Recurly
115
107
  end
116
108
 
117
109
  # allows configuration from a json string that contains the fields:
118
- # username,password,site,private_key
110
+ # api_key,site,private_key
119
111
  def configure_from_json(json_string)
120
112
  config_data = ActiveSupport::JSON.decode(json_string)
121
113
  configure do |c|
122
- c.username = config_data['username']
123
- c.password = config_data['password']
114
+ c.api_key = config_data['api_key'] || config_data['password']
124
115
  c.subdomain = config_data['subdomain']
125
116
  c.private_key = config_data['private_key']
126
117
  c.environment = config_data['environment']
@@ -1,4 +1,7 @@
1
+ require 'erb'
1
2
  require 'fileutils'
3
+ require 'yaml'
4
+
2
5
  module Recurly
3
6
  module ConfigParser
4
7
  class << self
@@ -7,7 +10,7 @@ module Recurly
7
10
  path ||= Recurly.settings_path
8
11
  settings = {}
9
12
  if File.exists?(path)
10
- settings = YAML.load_file(path) || {}
13
+ settings = YAML::load(ERB.new(File.read(path)).result) || {}
11
14
  else
12
15
  puts "\n#{path} file not found. Run rake recurly:setup to create one\n\n"
13
16
  end
@@ -25,4 +28,4 @@ module Recurly
25
28
  end
26
29
  end
27
30
 
28
- end
31
+ end
@@ -1,7 +1,6 @@
1
1
  module Recurly
2
2
  class Plan < Base
3
3
  self.element_name = "plan"
4
- self.prefix = "/site/"
5
4
  self.primary_key = :plan_code
6
5
 
7
6
  def self.known_attributes
@@ -6,7 +6,7 @@ namespace :recurly do
6
6
  @recurly_config = Recurly::ConfigParser.parse
7
7
  end
8
8
 
9
- desc "Clears out the Test data from your configured Recurly site (does not touch your production site)"
9
+ desc "Clears out the Test data from your configured Recurly site (does not touch your data in production mode)"
10
10
  task :clear_test_data => :load_settings do
11
11
  puts "\n"
12
12
 
@@ -17,42 +17,26 @@ namespace :recurly do
17
17
  exit
18
18
  end
19
19
 
20
- username = @recurly_config["username"]
21
- password = @recurly_config["password"]
22
-
23
- # lets try logging into site
24
- login_response = nil
25
- begin
26
- RestClient.post "https://app.recurly.com/login",
27
- :user_session => {
28
- :email => username,
29
- :password => password
30
- }
31
-
32
- # yes, RestClient api is weird
33
- raise "Login Failed for #{username} (we should have gotten a redirect)"
34
- rescue RestClient::Found => e
35
- # we got a redirect. horray!
36
- login_response = e.response
37
- end
20
+ api_key = @recurly_config["api_key"]
21
+ environment = @recurly_config["environment"]
38
22
 
39
23
  # now lets clear site data
40
24
  begin
41
- RestClient.post( @recurly_config["site"]+"/site/test_data",
42
- {"_method"=>"delete"},
43
- :cookies => login_response.cookies)
25
+ if environment == :development
26
+ RestClient.delete("http://#{api_key}@api.lvh.me:3000/configuration/test_data")
27
+ else
28
+ RestClient.delete("https://#{api_key}@api.recurly.com/configuration/test_data")
29
+ end
44
30
  raise "Clearing Didn't work for some reason. Is your site setting correct?"
45
31
  rescue RestClient::Found => e
46
- puts "Test Data Cleared from: #{@recurly_config["site"]}"
32
+ puts "Test Data Cleared"
47
33
  end
48
34
  end
49
35
 
50
36
  def setup_static
51
- @recurly_config["username"] ||= "myemail@mydomain.com"
52
- @recurly_config["password"] ||= "my_api_key"
37
+ @recurly_config["api_key"] ||= "my_api_key"
53
38
  @recurly_config["private_key"] ||= "my_private_key"
54
39
  @recurly_config["subdomain"] ||= "mysite"
55
- @recurly_config["site"] ||= "https://api-production.recurly.com"
56
40
  end
57
41
 
58
42
  desc "Creates a recurly.yml config file"
@@ -1,3 +1,5 @@
1
+ require 'erb'
2
+
1
3
  module Recurly
2
4
 
3
5
  module Action
@@ -1,5 +1,10 @@
1
1
  module Recurly
2
2
  module Verification
3
+
4
+ def stringify_keys data
5
+ Hash[data.map { |k, v| [k.to_s, v] }]
6
+ end
7
+
3
8
  class PreEscapedString < String
4
9
  end
5
10
 
@@ -8,7 +13,8 @@ module Recurly
8
13
  return nil if data.empty?
9
14
  PreEscapedString.new( '[%s]' % data.map{|v|digest_data(v)}.compact.join(',') )
10
15
  elsif data.is_a? Hash
11
- digest_data Hash[data.sort].map {|k,v|
16
+ data = stringify_keys data
17
+ digest_data data.sort.map {|k,v|
12
18
  prefix = (k =~ /\A\d+\Z/) ? '' : (k.to_s+':')
13
19
  (v=digest_data(v)).nil? ? nil : PreEscapedString.new('%s%s' % [prefix,v])
14
20
  }
@@ -35,11 +41,11 @@ module Recurly
35
41
 
36
42
  # Raises a Recurly::ForgedQueryString exception if the signature cannot be validated
37
43
  def verify_params!(claim, args)
38
- args = Hash[args.map { |k, v| [k.to_s, v] }]
44
+ args = stringify_keys args
39
45
  signature = args.delete('signature') or raise Recurly::ForgedQueryString.new('Signature is missing')
40
46
  hmac, timestamp = signature.split('-')
41
47
  age = Time.now.to_i - timestamp.to_i
42
- raise Recurly::ForgedQueryString.new('Timestamp is too old or new') if age > 3600 || age < 0
48
+ raise Recurly::ForgedQueryString.new('Timestamp is too old or new') if age > 3600 || age < -3600
43
49
 
44
50
  if signature != generate_signature(claim, args, timestamp)
45
51
  raise Recurly::ForgedQueryString.new('Signature cannot be verified')
@@ -48,15 +54,15 @@ module Recurly
48
54
 
49
55
  def sign_billing_info_update(account_code)
50
56
  generate_signature('billinginfoupdate', {
51
- account_code: account_code
57
+ :account_code => account_code
52
58
  })
53
59
  end
54
60
 
55
- def sign_transaction(account_code, currency, amount_in_cents)
61
+ def sign_transaction(amount_in_cents, currency, account_code=nil)
56
62
  generate_signature('transactioncreate', {
57
- account_code: account_code,
58
- currency: currency,
59
- amount_in_cents: amount_in_cents
63
+ :account_code => account_code,
64
+ :currency => currency,
65
+ :amount_in_cents => amount_in_cents
60
66
  })
61
67
  end
62
68
 
@@ -1,3 +1,3 @@
1
1
  module Recurly #:nodoc
2
- VERSION = "0.4.11"
2
+ VERSION = "0.4.13"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  ---
2
- username: api-test@facebook-test.com
3
- password: 69d95a9768c745ecb5ac6864032ec970
2
+ username: hello@test.com
3
+ password: 2a655d41659d4ae0b37fcaec06331bf5
4
4
  private_key: 4cdbdfbb90f84b3c8fb4ca337d1b2cfc
5
- subdomain: facebook-test
5
+ subdomain: intuit
6
6
  environment: :development
@@ -1,6 +1,4 @@
1
1
  ---
2
- username: username1@recurly.com
3
- password: asdf4jk31
2
+ api_key: asdf4jk31
4
3
  subdomain: site1
5
4
  private_key: asdfasdfasdf
6
- environment: :production
@@ -1,11 +1,7 @@
1
1
  development:
2
- username: username1@recurly.com
3
- password: asdf4jk31
2
+ api_key: asdf4jk31
4
3
  subdomain: site1
5
- environment: :sandbox
6
4
 
7
5
  test:
8
- username: username2@recurly.com
9
- password: asdf4jk32
6
+ api_key: asdf4jk32
10
7
  subdomain: site2
11
- environment: :production
@@ -5,15 +5,13 @@ describe "RecurlyConfig" do
5
5
  context "loading from YML" do
6
6
  it "should load traditional configuration from a YML file" do
7
7
  Recurly.configure_from_yaml("#{File.dirname(__FILE__)}/../config/test1.yml")
8
- Recurly.username.should == "username1@recurly.com"
9
- Recurly.password.should == "asdf4jk31"
8
+ Recurly.api_key.should == "asdf4jk31"
10
9
  Recurly.subdomain.should == "site1"
11
10
  end
12
11
 
13
12
  it "should load configuration from a YML file based on running environment" do
14
13
  Recurly.configure_from_yaml("#{File.dirname(__FILE__)}/../config/test2.yml")
15
- Recurly.username.should == "username2@recurly.com"
16
- Recurly.password.should == "asdf4jk32"
14
+ Recurly.api_key.should == "asdf4jk32"
17
15
  Recurly.subdomain.should == "site2"
18
16
  end
19
17
  end
@@ -21,28 +19,23 @@ describe "RecurlyConfig" do
21
19
  context "loading from json" do
22
20
  it "should load configuration from a json config string" do
23
21
  Recurly.configure_from_json({
24
- :username => "someuser@heroku.com",
25
- :password => "somepass",
26
- :environment => :sandbox,
22
+ :api_key => "somepass",
27
23
  :subdomain => 'recurlytest3-test',
28
24
  }.to_json)
29
- Recurly.username.should == "someuser@heroku.com"
30
- Recurly.password.should == "somepass"
25
+ Recurly.api_key.should == "somepass"
31
26
  Recurly.subdomain.should == 'recurlytest3-test'
32
- Recurly::Base.site.to_s.should == "https://api-sandbox.recurly.com"
27
+ Recurly::Base.site.to_s.should == "https://api.recurly.com"
33
28
 
34
29
  # test with some crazy chars in the password
35
30
  Recurly.configure_from_json({
36
- :username => "api-someuser@heroku.com",
37
- :password => "*$&!!::@&!)*)*_",
31
+ :api_key => "*$&!!::@&!)*)*_",
38
32
  :subdomain => "recurlytest3-test",
39
- :environment => :sandbox,
40
33
  }.to_json)
41
34
 
42
- Recurly.username.should == "api-someuser@heroku.com"
43
- Recurly.password.should == "*$&!!::@&!)*)*_"
35
+ Recurly.api_key.should == "*$&!!::@&!)*)*_"
36
+ Recurly::Base.user.should == Recurly.api_key
44
37
  Recurly.subdomain.should == 'recurlytest3-test'
45
- Recurly::Base.site.to_s.should == "https://api-sandbox.recurly.com"
38
+ Recurly::Base.site.to_s.should == "https://api.recurly.com"
46
39
  end
47
40
 
48
41
  end
@@ -16,26 +16,6 @@ module Recurly
16
16
  Transparent.url(Action::UpdateBilling).should == "#{Recurly::Base.site}/transparent/#{Recurly.subdomain}/billing_info"
17
17
  Transparent.url(Action::CreateTransaction).should == "#{Recurly::Base.site}/transparent/#{Recurly.subdomain}/transaction"
18
18
  end
19
-
20
- it "should equal api-sandbox for sandbox" do
21
- Recurly.configure do |config|
22
- config.environment = :sandbox
23
- config.subdomain = 'testtest'
24
- end
25
- Transparent.url(Action::CreateSubscription).should == "#{Recurly::Base.site}/transparent/testtest/subscription"
26
- Transparent.url(Action::UpdateBilling).should == "#{Recurly::Base.site}/transparent/testtest/billing_info"
27
- Transparent.url(Action::CreateTransaction).should == "#{Recurly::Base.site}/transparent/testtest/transaction"
28
- end
29
-
30
- it "should equal api-production for sandbox" do
31
- Recurly.configure do |config|
32
- config.environment = :production
33
- config.subdomain = 'testtest'
34
- end
35
- Transparent.url(Action::CreateSubscription).should == "#{Recurly::Base.site}/transparent/testtest/subscription"
36
- Transparent.url(Action::UpdateBilling).should == "#{Recurly::Base.site}/transparent/testtest/billing_info"
37
- Transparent.url(Action::CreateTransaction).should == "#{Recurly::Base.site}/transparent/testtest/transaction"
38
- end
39
19
  end
40
20
 
41
21
  describe ".encrypt_string" do
@@ -18,10 +18,16 @@ module Recurly
18
18
 
19
19
  it "should encode nested arrays and hashes" do
20
20
  Verification::digest_data(
21
- {a: [1,2,3], b: {c: '123', d:'456'}}
21
+ {:a => [1,2,3], :b => {:c => '123', :d => '456'}}
22
22
  ).should == '[a:[1,2,3],b:[c:123,d:456]]'
23
23
  end
24
24
 
25
+ it "should alphabetize keys" do
26
+ Verification::digest_data(
27
+ {:a => 1, :c => 3, :b => 2}
28
+ ).should == '[a:1,b:2,c:3]'
29
+ end
30
+
25
31
  it "should treat hashes with numeric indexes as arrays" do
26
32
  Verification::digest_data(
27
33
  {'1' => 4, '2' => 5, '3' => 6}
@@ -30,13 +36,13 @@ module Recurly
30
36
 
31
37
  it "should escape syntax characters" do
32
38
  Verification::digest_data(
33
- {syntaxchars: ' \\ [ ] : , '}
39
+ { :syntaxchars => ' \\ [ ] : , '}
34
40
  ).should == '[syntaxchars: \\\\ \[ \] \: \, ]'
35
41
  end
36
42
 
37
43
  it "should generate proper signatures" do
38
44
  Time.stub!(:now).and_return(origin_time) # gen at origin time
39
- sig = Verification.generate_signature('update',{a:'foo',b:'bar'})
45
+ sig = Verification.generate_signature('update',{ :a => 'foo', :b => 'bar'})
40
46
  sig.should == test_sig
41
47
  end
42
48
 
@@ -44,7 +50,7 @@ module Recurly
44
50
  Time.stub!(:now).and_return(Time.at(origin_time+60)) # one minute passed
45
51
  lambda {
46
52
  good = Verification.verify_params!('update',
47
- {a:'foo',b:'bar',signature:test_sig})
53
+ { :a => 'foo', :b => 'bar', :signature => test_sig})
48
54
  }.should_not raise_error
49
55
  end
50
56
 
@@ -52,7 +58,7 @@ module Recurly
52
58
  Time.stub!(:now).and_return(Time.at(origin_time+60)) # one minute passed
53
59
  lambda {
54
60
  good = Verification.verify_params!('update',
55
- {a:'foo',b:'bar',signature:'badsig'})
61
+ { :a => 'foo', :b => 'bar', :signature => 'badsig'})
56
62
  }.should raise_error(Recurly::ForgedQueryString)
57
63
  end
58
64
 
@@ -60,15 +66,15 @@ module Recurly
60
66
  Time.stub!(:now).and_return(Time.at(origin_time+7200)) # two hours passed
61
67
  lambda {
62
68
  good = Verification.verify_params!('update',
63
- {a:'foo',b:'bar',signature:test_sig})
69
+ { :a => 'foo', :b => 'bar', :signature => test_sig})
64
70
  }.should raise_error(Recurly::ForgedQueryString)
65
71
  end
66
72
 
67
- it "should reject time traveling signatures from the future" do
68
- Time.stub!(:now).and_return(Time.at(origin_time-60)) # one minute earlier
73
+ it "should reject time traveling signatures from the future (with 1 hour grace period)" do
74
+ Time.stub!(:now).and_return(Time.at(origin_time-7200)) # two hours earlier
69
75
  lambda {
70
76
  good = Verification.verify_params!('update',
71
- {a:'foo',b:'bar',signature:test_sig})
77
+ { :a => 'foo', :b => 'bar', :signature => test_sig})
72
78
  }.should raise_error(Recurly::ForgedQueryString)
73
79
  end
74
80
  end