stripe-ruby-mock 3.1.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b5b1b83df91e8e6fd700456710804749b9b1008e572fd8c74eec4f1519e8a49
4
- data.tar.gz: bf362cf2fe9aa556e155df2b61076248335e3b2a43f69e0e6fc046406d65da57
3
+ metadata.gz: be25dafb9048c0f9fea9671c8dfa3c25f51121afcd11e2a83fb28033d84fb609
4
+ data.tar.gz: 5ccd183891c8ee2a67aa21b7be2508226850a514b9d1f5c8bbe994e374b832df
5
5
  SHA512:
6
- metadata.gz: a397bf1b196f62bb7c8d76f79e2582f6d6594d20ddb9473b8dd5e7680c1844620a29456cddd8be8c5d9b785f4317ea1b092b340f841ccdbef92d849c6bb116e7
7
- data.tar.gz: 90f97fe65c4dcd10eaa853aec740bce21c56b8df57bc1a589acc6f13ebf1b65943731b50f820d9f8eaa77954673f78b34bb62b326cbb7c71f5692a0b74a347c0
6
+ metadata.gz: d3be1ba24da98944abb23977d94ab25205ef5458fbe1504bff4293fa55b6d0ae57f922ede65d28f80872c60e66086fd68a32f5b4a96dd5c23ab59a20639f1c74
7
+ data.tar.gz: b06bea97f9417cfaf61e4c4a4dc86c914ef1dc76ec170bda9514fd782eddabeceac62b60a65fef771220b59c7b83aeba0c60a809a641c0b02984c1fa8378ce15
@@ -22,7 +22,7 @@ jobs:
22
22
  runs-on: ubuntu-latest
23
23
  strategy:
24
24
  matrix:
25
- ruby-version: ['2.6', '2.7', '3.0']
25
+ ruby-version: ['2.7', '3.0', '3.2']
26
26
 
27
27
  steps:
28
28
  - uses: actions/checkout@v3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ### Unreleased
2
2
 
3
+ ### 4.0.0 (2024-08-07)
4
+ - [#905](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/905) Allow Stripe SDK v11 by [@stevenharman ](https://github.com/stevenharman)
5
+ - [#830](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/830) Implement search API by [@adamstegman](https://github.com/adamstegman)
6
+ - [#848](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/848) Extending runtime dependency on Stripe gem from version 5 through 11 by [@smakani](https://github.com/smakani)
7
+ - [#893](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/893) Adds support for stripe-ruby v10 by [@fabianoarruda](https://github.com/fabianoarruda)
8
+
9
+
10
+ ### 3.1.0 (2024-01-03)
3
11
  - [#693](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/693) gemspec: add change,issue,source_code URL by [@mtmail](https://github.com/mtmail)
4
12
  - [#700](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/700) update the balance API to respond with instant_available by [@iamnader](https://github.com/iamnader)
5
13
  - [#687](https://github.com/stripe-ruby-mock/stripe-ruby-mock/pull/687) Add PaymentIntent Webhooks by [@klaustopher](https://github.com/klaustopher)
data/Gemfile CHANGED
@@ -1,10 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- platforms :ruby_19 do
4
- gem 'mime-types', '~> 2.6'
5
- gem 'rest-client', '~> 1.8'
6
- end
7
-
8
3
  group :test do
9
4
  gem 'rake'
10
5
  gem 'dotenv'
data/README.md CHANGED
@@ -12,7 +12,7 @@ This gem has unexpectedly grown in popularity and I've gotten pretty busy, so I'
12
12
 
13
13
  In your gemfile:
14
14
 
15
- gem 'stripe-ruby-mock', '~> 3.1.0', :require => 'stripe_mock'
15
+ gem 'stripe-ruby-mock', :require => 'stripe_mock'
16
16
 
17
17
  ## !!! Important
18
18
 
@@ -29,8 +29,8 @@ version `3.0.0` has [breaking changes](https://github.com/stripe-ruby-mock/strip
29
29
 
30
30
  ### Requirements
31
31
 
32
- * ruby >= 2.6.0
33
- * stripe >= 5.0.0
32
+ * ruby >= 2.7.0
33
+ * stripe > 5 & < 11
34
34
 
35
35
  ### Specifications
36
36
 
@@ -27,7 +27,7 @@ module StripeMock
27
27
 
28
28
  private
29
29
 
30
- def self.redirect_to_mock_server(method, url, api_key: nil, api_base: nil, params: {}, headers: {})
30
+ def self.redirect_to_mock_server(method, url, api_key: nil, api_base: nil, usage: [], params: {}, headers: {})
31
31
  handler = Instance.handler_for_method_url("#{method} #{url}")
32
32
 
33
33
  if mock_error = client.error_queue.error_for_handler_name(handler[:name])
@@ -109,7 +109,7 @@ module StripeMock
109
109
  @base_strategy = TestStrategies::Base.new
110
110
  end
111
111
 
112
- def mock_request(method, url, api_key: nil, api_base: nil, params: {}, headers: {})
112
+ def mock_request(method, url, api_key: nil, api_base: nil, usage: [], params: {}, headers: {})
113
113
  return {} if method == :xtest
114
114
 
115
115
  api_key ||= (Stripe.api_key || DUMMY_API_KEY)
@@ -5,7 +5,8 @@ module StripeMock
5
5
  def Charges.included(klass)
6
6
  klass.add_handler 'post /v1/charges', :new_charge
7
7
  klass.add_handler 'get /v1/charges', :get_charges
8
- klass.add_handler 'get /v1/charges/(.*)', :get_charge
8
+ klass.add_handler 'get /v1/charges/search', :search_charges
9
+ klass.add_handler 'get /v1/charges/((?!search).*)', :get_charge
9
10
  klass.add_handler 'post /v1/charges/(.*)/capture', :capture_charge
10
11
  klass.add_handler 'post /v1/charges/(.*)/refund', :refund_charge
11
12
  klass.add_handler 'post /v1/charges/(.*)/refunds', :refund_charge
@@ -90,6 +91,24 @@ module StripeMock
90
91
  Data.mock_list_object(clone.values, params)
91
92
  end
92
93
 
94
+ SEARCH_FIELDS = [
95
+ "amount",
96
+ "currency",
97
+ "customer",
98
+ "payment_method_details.card.brand",
99
+ "payment_method_details.card.exp_month",
100
+ "payment_method_details.card.exp_year",
101
+ "payment_method_details.card.fingerprint",
102
+ "payment_method_details.card.last4",
103
+ "status",
104
+ ].freeze
105
+ def search_charges(route, method_url, params, headers)
106
+ require_param(:query) unless params[:query]
107
+
108
+ results = search_results(charges.values, params[:query], fields: SEARCH_FIELDS, resource_name: "charges")
109
+ Data.mock_list_object(results, params)
110
+ end
111
+
93
112
  def get_charge(route, method_url, params, headers)
94
113
  route =~ method_url
95
114
  charge_id = $1 || params[:charge]
@@ -5,9 +5,10 @@ module StripeMock
5
5
  def Customers.included(klass)
6
6
  klass.add_handler 'post /v1/customers', :new_customer
7
7
  klass.add_handler 'post /v1/customers/([^/]*)', :update_customer
8
- klass.add_handler 'get /v1/customers/([^/]*)', :get_customer
8
+ klass.add_handler 'get /v1/customers/((?!search)[^/]*)', :get_customer
9
9
  klass.add_handler 'delete /v1/customers/([^/]*)', :delete_customer
10
10
  klass.add_handler 'get /v1/customers', :list_customers
11
+ klass.add_handler 'get /v1/customers/search', :search_customers
11
12
  klass.add_handler 'delete /v1/customers/([^/]*)/discount', :delete_customer_discount
12
13
  end
13
14
 
@@ -140,6 +141,16 @@ module StripeMock
140
141
  Data.mock_list_object(customers[stripe_account]&.values, params)
141
142
  end
142
143
 
144
+ SEARCH_FIELDS = ["email", "name", "phone"].freeze
145
+ def search_customers(route, method_url, params, headers)
146
+ require_param(:query) unless params[:query]
147
+
148
+ stripe_account = headers && headers[:stripe_account] || Stripe.api_key
149
+ all_customers = customers[stripe_account]&.values
150
+ results = search_results(all_customers, params[:query], fields: SEARCH_FIELDS, resource_name: "customers")
151
+ Data.mock_list_object(results, params)
152
+ end
153
+
143
154
  def delete_customer_discount(route, method_url, params, headers)
144
155
  stripe_account = headers && headers[:stripe_account] || Stripe.api_key
145
156
  route =~ method_url
@@ -0,0 +1,67 @@
1
+ module StripeMock
2
+ module RequestHandlers
3
+ module Helpers
4
+ # Only supports exact matches on a single field, e.g.
5
+ # - 'amount:100'
6
+ # - 'email:"name@domain.com"'
7
+ # - 'name:"Foo Bar"'
8
+ # - 'metadata["foo"]:"bar"'
9
+ QUERYSTRING_PATTERN = /\A(?<field>[\w\.]+)(\[['"](?<metadata_key>[^'"]*)['"]\])?:['"]?(?<value>[^'"]*)['"]?\z/
10
+ def search_results(all_values, querystring, fields: [], resource_name:)
11
+ values = all_values.dup
12
+ query_match = QUERYSTRING_PATTERN.match(querystring)
13
+ raise Stripe::InvalidRequestError.new(
14
+ 'We were unable to parse your search query.' \
15
+ ' Try using the format `metadata["key"]:"value"` to query for metadata or key:"value" to query for other fields.',
16
+ nil,
17
+ http_status: 400,
18
+ ) unless query_match
19
+
20
+ case query_match[:field]
21
+ when *fields
22
+ values = values.select { |resource|
23
+ exact_match?(actual: field_value(resource, field: query_match[:field]), expected: query_match[:value])
24
+ }
25
+ when "metadata"
26
+ values = values.select { |resource|
27
+ resource[:metadata] &&
28
+ exact_match?(actual: resource[:metadata][query_match[:metadata_key].to_sym], expected: query_match[:value])
29
+ }
30
+ else
31
+ raise Stripe::InvalidRequestError.new(
32
+ "Field `#{query_match[:field]}` is an unsupported search field for resource `#{resource_name}`." \
33
+ " See http://stripe.com/docs/search#query-fields-for-#{resource_name.gsub('_', '-')} for a list of supported fields.",
34
+ nil,
35
+ http_status: 400,
36
+ )
37
+ end
38
+
39
+ values
40
+ end
41
+
42
+ def exact_match?(actual:, expected:)
43
+ # allow comparisons of integers
44
+ if actual.respond_to?(:to_i) && actual.to_i == actual
45
+ expected = expected.to_i
46
+ end
47
+ # allow comparisons of boolean
48
+ case expected
49
+ when "true"
50
+ expected = true
51
+ when "false"
52
+ expected = false
53
+ end
54
+
55
+ actual == expected
56
+ end
57
+
58
+ def field_value(resource, field:)
59
+ value = resource
60
+ field.split('.').each do |segment|
61
+ value = value[segment.to_sym]
62
+ end
63
+ value
64
+ end
65
+ end
66
+ end
67
+ end
@@ -6,7 +6,8 @@ module StripeMock
6
6
  klass.add_handler 'post /v1/invoices', :new_invoice
7
7
  klass.add_handler 'get /v1/invoices/upcoming', :upcoming_invoice
8
8
  klass.add_handler 'get /v1/invoices/(.*)/lines', :get_invoice_line_items
9
- klass.add_handler 'get /v1/invoices/(.*)', :get_invoice
9
+ klass.add_handler 'get /v1/invoices/((?!search).*)', :get_invoice
10
+ klass.add_handler 'get /v1/invoices/search', :search_invoices
10
11
  klass.add_handler 'get /v1/invoices', :list_invoices
11
12
  klass.add_handler 'post /v1/invoices/(.*)/pay', :pay_invoice
12
13
  klass.add_handler 'post /v1/invoices/(.*)', :update_invoice
@@ -25,6 +26,14 @@ module StripeMock
25
26
  invoices[$1].merge!(params)
26
27
  end
27
28
 
29
+ SEARCH_FIELDS = ["currency", "customer", "number", "receipt_number", "subscription", "total"].freeze
30
+ def search_invoices(route, method_url, params, headers)
31
+ require_param(:query) unless params[:query]
32
+
33
+ results = search_results(invoices.values, params[:query], fields: SEARCH_FIELDS, resource_name: "invoices")
34
+ Data.mock_list_object(results, params)
35
+ end
36
+
28
37
  def list_invoices(route, method_url, params, headers)
29
38
  params[:offset] ||= 0
30
39
  params[:limit] ||= 10
@@ -6,7 +6,8 @@ module StripeMock
6
6
  def PaymentIntents.included(klass)
7
7
  klass.add_handler 'post /v1/payment_intents', :new_payment_intent
8
8
  klass.add_handler 'get /v1/payment_intents', :get_payment_intents
9
- klass.add_handler 'get /v1/payment_intents/(.*)', :get_payment_intent
9
+ klass.add_handler 'get /v1/payment_intents/((?!search).*)', :get_payment_intent
10
+ klass.add_handler 'get /v1/payment_intents/search', :search_payment_intents
10
11
  klass.add_handler 'post /v1/payment_intents/(.*)/confirm', :confirm_payment_intent
11
12
  klass.add_handler 'post /v1/payment_intents/(.*)/capture', :capture_payment_intent
12
13
  klass.add_handler 'post /v1/payment_intents/(.*)/cancel', :cancel_payment_intent
@@ -70,6 +71,14 @@ module StripeMock
70
71
  payment_intent
71
72
  end
72
73
 
74
+ SEARCH_FIELDS = ["amount", "currency", "customer", "status"].freeze
75
+ def search_payment_intents(route, method_url, params, headers)
76
+ require_param(:query) unless params[:query]
77
+
78
+ results = search_results(payment_intents.values, params[:query], fields: SEARCH_FIELDS, resource_name: "payment_intents")
79
+ Data.mock_list_object(results, params)
80
+ end
81
+
73
82
  def capture_payment_intent(route, method_url, params, headers)
74
83
  route =~ method_url
75
84
  payment_intent = assert_existence :payment_intent, $1, payment_intents[$1]
@@ -3,10 +3,11 @@ module StripeMock
3
3
  module Prices
4
4
 
5
5
  def Prices.included(klass)
6
- klass.add_handler 'post /v1/prices', :new_price
7
- klass.add_handler 'post /v1/prices/(.*)', :update_price
8
- klass.add_handler 'get /v1/prices/(.*)', :get_price
9
- klass.add_handler 'get /v1/prices', :list_prices
6
+ klass.add_handler 'post /v1/prices', :new_price
7
+ klass.add_handler 'post /v1/prices/(.*)', :update_price
8
+ klass.add_handler 'get /v1/prices/((?!search).*)', :get_price
9
+ klass.add_handler 'get /v1/prices/search', :search_prices
10
+ klass.add_handler 'get /v1/prices', :list_prices
10
11
  end
11
12
 
12
13
  def new_price(route, method_url, params, headers)
@@ -57,6 +58,14 @@ module StripeMock
57
58
 
58
59
  Data.mock_list_object(price_data.first(limit), params.merge!(limit: limit))
59
60
  end
61
+
62
+ SEARCH_FIELDS = ["active", "currency", "lookup_key", "product", "type"].freeze
63
+ def search_prices(route, method_url, params, headers)
64
+ require_param(:query) unless params[:query]
65
+
66
+ results = search_results(prices.values, params[:query], fields: SEARCH_FIELDS, resource_name: "prices")
67
+ Data.mock_list_object(results, params)
68
+ end
60
69
  end
61
70
  end
62
71
  end
@@ -2,11 +2,12 @@ module StripeMock
2
2
  module RequestHandlers
3
3
  module Products
4
4
  def self.included(base)
5
- base.add_handler 'post /v1/products', :create_product
6
- base.add_handler 'get /v1/products/(.*)', :retrieve_product
7
- base.add_handler 'post /v1/products/(.*)', :update_product
8
- base.add_handler 'get /v1/products', :list_products
9
- base.add_handler 'delete /v1/products/(.*)', :destroy_product
5
+ base.add_handler 'post /v1/products', :create_product
6
+ base.add_handler 'get /v1/products/((?!search).*)', :retrieve_product
7
+ base.add_handler 'get /v1/products/search', :search_products
8
+ base.add_handler 'post /v1/products/(.*)', :update_product
9
+ base.add_handler 'get /v1/products', :list_products
10
+ base.add_handler 'delete /v1/products/(.*)', :destroy_product
10
11
  end
11
12
 
12
13
  def create_product(_route, _method_url, params, _headers)
@@ -32,6 +33,14 @@ module StripeMock
32
33
  Data.mock_list_object(products.values.take(limit), params)
33
34
  end
34
35
 
36
+ SEARCH_FIELDS = ["active", "description", "name", "shippable", "url"].freeze
37
+ def search_products(route, method_url, params, headers)
38
+ require_param(:query) unless params[:query]
39
+
40
+ results = search_results(products.values, params[:query], fields: SEARCH_FIELDS, resource_name: "products")
41
+ Data.mock_list_object(results, params)
42
+ end
43
+
35
44
  def destroy_product(route, method_url, _params, _headers)
36
45
  id = method_url.match(route).captures.first
37
46
  assert_existence :product, id, products[id]
@@ -5,8 +5,9 @@ module StripeMock
5
5
  def Subscriptions.included(klass)
6
6
  klass.add_handler 'get /v1/subscriptions', :retrieve_subscriptions
7
7
  klass.add_handler 'post /v1/subscriptions', :create_subscription
8
- klass.add_handler 'get /v1/subscriptions/(.*)', :retrieve_subscription
8
+ klass.add_handler 'get /v1/subscriptions/((?!search).*)', :retrieve_subscription
9
9
  klass.add_handler 'post /v1/subscriptions/(.*)', :update_subscription
10
+ klass.add_handler 'get /v1/subscriptions/search', :search_subscriptions
10
11
  klass.add_handler 'delete /v1/subscriptions/(.*)', :cancel_subscription
11
12
 
12
13
  klass.add_handler 'post /v1/customers/(.*)/subscription(?:s)?', :create_customer_subscription
@@ -343,6 +344,14 @@ module StripeMock
343
344
  subscription
344
345
  end
345
346
 
347
+ SEARCH_FIELDS = ["status"].freeze
348
+ def search_subscriptions(route, method_url, params, headers)
349
+ require_param(:query) unless params[:query]
350
+
351
+ results = search_results(subscriptions.values, params[:query], fields: SEARCH_FIELDS, resource_name: "subscriptions")
352
+ Data.mock_list_object(results, params)
353
+ end
354
+
346
355
  private
347
356
 
348
357
  def get_subscription_plans_from_params(params)
@@ -1,4 +1,4 @@
1
1
  module StripeMock
2
2
  # stripe-ruby-mock version
3
- VERSION = "3.1.0"
3
+ VERSION = "4.0.0"
4
4
  end
data/lib/stripe_mock.rb CHANGED
@@ -42,6 +42,7 @@ require 'stripe_mock/request_handlers/helpers/external_account_helpers.rb'
42
42
  require 'stripe_mock/request_handlers/helpers/card_helpers.rb'
43
43
  require 'stripe_mock/request_handlers/helpers/charge_helpers.rb'
44
44
  require 'stripe_mock/request_handlers/helpers/coupon_helpers.rb'
45
+ require 'stripe_mock/request_handlers/helpers/search_helpers.rb'
45
46
  require 'stripe_mock/request_handlers/helpers/subscription_helpers.rb'
46
47
  require 'stripe_mock/request_handlers/helpers/token_helpers.rb'
47
48
 
@@ -28,20 +28,19 @@ shared_examples 'Bank Account Token Mocking' do
28
28
  expect(bank_token).to match /^test_btok/
29
29
  end
30
30
 
31
- it "assigns the generated bank account to a new recipient" do
31
+ it "assigns the generated bank account to a new customer" do
32
32
  bank_token = StripeMock.generate_bank_token(
33
33
  :bank_name => "Bank Token Mocking",
34
34
  :last4 => "7777"
35
35
  )
36
36
 
37
- recipient = Stripe::Recipient.create({
37
+ customer = Stripe::Customer.create({
38
38
  name: "Fred Flinstone",
39
- type: "individual",
40
39
  email: 'blah@domain.co',
41
- bank_account: bank_token
40
+ source: bank_token
42
41
  })
43
- expect(recipient.active_account.last4).to eq("7777")
44
- expect(recipient.active_account.bank_name).to eq("Bank Token Mocking")
42
+ expect(customer.sources.first.last4).to eq("7777")
43
+ expect(customer.sources.first.bank_name).to eq("Bank Token Mocking")
45
44
  end
46
45
 
47
46
  it "retrieves a created token" do
@@ -55,5 +54,4 @@ shared_examples 'Bank Account Token Mocking' do
55
54
  expect(token.bank_account.last4).to eq("3939")
56
55
  expect(token.bank_account.bank_name).to eq("Cha-ching Banking")
57
56
  end
58
-
59
57
  end
@@ -494,4 +494,101 @@ shared_examples 'Charge API' do
494
494
  end
495
495
  end
496
496
 
497
+ context "search" do
498
+ # the Search API requires about a minute between writes and reads, so add sleeps accordingly when running live
499
+ it "searches charges for exact matches", :aggregate_failures do
500
+ response = Stripe::Charge.search({query: 'amount:100'}, stripe_version: '2020-08-27')
501
+ expect(response.data.size).to eq(0)
502
+
503
+ customer = Stripe::Customer.create(email: 'johnny@appleseed.com')
504
+ one = Stripe::Charge.create(
505
+ customer: customer.id,
506
+ amount: 100,
507
+ currency: "usd",
508
+ payment_method_details: {
509
+ card: StripeMock::Data.mock_charge[:payment_method_details][:card].merge(
510
+ brand: "mastercard",
511
+ exp_month: 1,
512
+ exp_year: 2111,
513
+ fingerprint: "un",
514
+ last4: "1111",
515
+ ),
516
+ },
517
+ status: "succeeded",
518
+ metadata: {key: 'uno'},
519
+ )
520
+ two = Stripe::Charge.create(
521
+ customer: customer.id,
522
+ amount: 200,
523
+ currency: "gbp",
524
+ payment_method_details: {
525
+ card: StripeMock::Data.mock_charge[:payment_method_details][:card].merge(
526
+ brand: "visa",
527
+ exp_month: 2,
528
+ exp_year: 2222,
529
+ fingerprint: "deux",
530
+ last4: "2222",
531
+ ),
532
+ },
533
+ status: "pending",
534
+ metadata: {key: 'dos'},
535
+ )
536
+
537
+ response = Stripe::Charge.search({query: 'amount:100'}, stripe_version: '2020-08-27')
538
+ expect(response.data.map(&:id)).to match_array([one.id])
539
+
540
+ response = Stripe::Charge.search({query: 'currency:"gbp"'}, stripe_version: '2020-08-27')
541
+ expect(response.data.map(&:id)).to match_array([two.id])
542
+
543
+ response = Stripe::Charge.search({query: %(customer:"#{customer.id}")}, stripe_version: '2020-08-27')
544
+ expect(response.data.map(&:id)).to match_array([one.id, two.id])
545
+
546
+ response = Stripe::Charge.search({query: 'payment_method_details.card.brand:mastercard'}, stripe_version: '2020-08-27')
547
+ expect(response.data.map(&:id)).to match_array([one.id])
548
+
549
+ response = Stripe::Charge.search({query: 'payment_method_details.card.exp_month:2'}, stripe_version: '2020-08-27')
550
+ expect(response.data.map(&:id)).to match_array([two.id])
551
+
552
+ response = Stripe::Charge.search({query: 'payment_method_details.card.exp_year:2111'}, stripe_version: '2020-08-27')
553
+ expect(response.data.map(&:id)).to match_array([one.id])
554
+
555
+ response = Stripe::Charge.search({query: 'payment_method_details.card.fingerprint:un'}, stripe_version: '2020-08-27')
556
+ expect(response.data.map(&:id)).to match_array([one.id])
557
+
558
+ response = Stripe::Charge.search({query: 'payment_method_details.card.last4:2222'}, stripe_version: '2020-08-27')
559
+ expect(response.data.map(&:id)).to match_array([two.id])
560
+
561
+ response = Stripe::Charge.search({query: 'status:"succeeded"'}, stripe_version: '2020-08-27')
562
+ expect(response.data.map(&:id)).to match_array([one.id])
563
+
564
+ response = Stripe::Charge.search({query: 'metadata["key"]:"uno"'}, stripe_version: '2020-08-27')
565
+ expect(response.data.map(&:id)).to match_array([one.id])
566
+ end
567
+
568
+ it "respects limit", :aggregate_failures do
569
+ customer = Stripe::Customer.create(email: 'johnny@appleseed.com')
570
+ 11.times do
571
+ Stripe::Charge.create(customer: customer.id, amount: 100, currency: "usd")
572
+ end
573
+
574
+ response = Stripe::Charge.search({query: %(customer:"#{customer.id}")}, stripe_version: '2020-08-27')
575
+ expect(response.data.size).to eq(10)
576
+ response = Stripe::Charge.search({query: %(customer:"#{customer.id}"), limit: 1}, stripe_version: '2020-08-27')
577
+ expect(response.data.size).to eq(1)
578
+ end
579
+
580
+ it "reports search errors", :aggregate_failures do
581
+ expect {
582
+ Stripe::Charge.search({limit: 1}, stripe_version: '2020-08-27')
583
+ }.to raise_error(Stripe::InvalidRequestError, /Missing required param: query./)
584
+
585
+ expect {
586
+ Stripe::Charge.search({query: 'asdf'}, stripe_version: '2020-08-27')
587
+ }.to raise_error(Stripe::InvalidRequestError, /We were unable to parse your search query./)
588
+
589
+ expect {
590
+ Stripe::Charge.search({query: 'foo:"bar"'}, stripe_version: '2020-08-27')
591
+ }.to raise_error(Stripe::InvalidRequestError, /Field `foo` is an unsupported search field for resource `charges`./)
592
+ end
593
+ end
497
594
  end
@@ -349,6 +349,62 @@ shared_examples 'Customer API' do
349
349
  expect(all.data.map &:email).to include('one@one.com', 'two@two.com')
350
350
  end
351
351
 
352
+ context "search" do
353
+ # the Search API requires about a minute between writes and reads, so add sleeps accordingly when running live
354
+ it "searches customers for exact matches", :aggregate_failures do
355
+ response = Stripe::Customer.search({query: 'email:"one@one.com"'}, stripe_version: '2020-08-27')
356
+ expect(response.data.size).to eq(0)
357
+
358
+ one = Stripe::Customer.create(email: 'one@one.com', name: 'one', phone: '1111111111', metadata: {key: 'uno'})
359
+ two = Stripe::Customer.create(email: 'two@two.com', name: 'two', phone: '2222222222', metadata: {key: 'dos'})
360
+
361
+ response = Stripe::Customer.search({query: 'email:"one@one.com"'}, stripe_version: '2020-08-27')
362
+ expect(response.data.map(&:id)).to match_array([one.id])
363
+
364
+ response = Stripe::Customer.search({query: 'name:"two"'}, stripe_version: '2020-08-27')
365
+ expect(response.data.map(&:id)).to match_array([two.id])
366
+
367
+ response = Stripe::Customer.search({query: 'phone:"2222222222"'}, stripe_version: '2020-08-27')
368
+ expect(response.data.map(&:id)).to match_array([two.id])
369
+
370
+ response = Stripe::Customer.search({query: 'metadata["key"]:"uno"'}, stripe_version: '2020-08-27')
371
+ expect(response.data.map(&:id)).to match_array([one.id])
372
+ end
373
+
374
+ it "respects limit", :aggregate_failures do
375
+ one = Stripe::Customer.create(email: 'one@one.com', name: 'one')
376
+ two = Stripe::Customer.create(email: 'two@two.com', name: 'one')
377
+ three = Stripe::Customer.create(email: 'three@three.com', name: 'one')
378
+ four = Stripe::Customer.create(email: 'four@four.com', name: 'one')
379
+ five = Stripe::Customer.create(email: 'five@five.com', name: 'one')
380
+ six = Stripe::Customer.create(email: 'six@six.com', name: 'one')
381
+ seven = Stripe::Customer.create(email: 'seven@seven.com', name: 'one')
382
+ eight = Stripe::Customer.create(email: 'eight@eight.com', name: 'one')
383
+ nine = Stripe::Customer.create(email: 'nine@nine.com', name: 'one')
384
+ ten = Stripe::Customer.create(email: 'ten@ten.com', name: 'one')
385
+ eleven = Stripe::Customer.create(email: 'eleven@eleven.com', name: 'one')
386
+
387
+ response = Stripe::Customer.search({query: 'name:"one"'}, stripe_version: '2020-08-27')
388
+ expect(response.data.size).to eq(10)
389
+ response = Stripe::Customer.search({query: 'name:"one"', limit: 1}, stripe_version: '2020-08-27')
390
+ expect(response.data.size).to eq(1)
391
+ end
392
+
393
+ it "reports search errors", :aggregate_failures do
394
+ expect {
395
+ Stripe::Customer.search({limit: 1}, stripe_version: '2020-08-27')
396
+ }.to raise_error(Stripe::InvalidRequestError, /Missing required param: query./)
397
+
398
+ expect {
399
+ Stripe::Customer.search({query: 'asdf'}, stripe_version: '2020-08-27')
400
+ }.to raise_error(Stripe::InvalidRequestError, /We were unable to parse your search query./)
401
+
402
+ expect {
403
+ Stripe::Customer.search({query: 'foo:"bar"'}, stripe_version: '2020-08-27')
404
+ }.to raise_error(Stripe::InvalidRequestError, /Field `foo` is an unsupported search field for resource `customers`./)
405
+ end
406
+ end
407
+
352
408
  it "updates a stripe customer" do
353
409
  original = Stripe::Customer.create(id: 'test_customer_update')
354
410
  email = original.email
@@ -79,6 +79,88 @@ shared_examples 'Invoice API' do
79
79
  end
80
80
  end
81
81
 
82
+ context "searching invoices" do
83
+ # the Search API requires about a minute between writes and reads, so add sleeps accordingly when running live
84
+ it "searches invoices for exact matches", :aggregate_failures do
85
+ response = Stripe::Invoice.search({query: 'currency:"usd"'}, stripe_version: '2020-08-27')
86
+ expect(response.data.size).to eq(0)
87
+
88
+ product = stripe_helper.create_product
89
+ stripe_helper.create_plan(
90
+ amount: 500,
91
+ interval: 'month',
92
+ product: product.id,
93
+ currency: 'usd',
94
+ id: 'Sample5',
95
+ )
96
+ customer = Stripe::Customer.create(email: 'johnny@appleseed.com', source: stripe_helper.generate_card_token)
97
+ subscription = Stripe::Subscription.create(customer: customer.id, items: [{plan: 'Sample5'}])
98
+ one = Stripe::Invoice.create(
99
+ customer: customer.id,
100
+ currency: 'usd',
101
+ subscription: subscription.id,
102
+ metadata: {key: 'uno'},
103
+ number: 'one-1',
104
+ receipt_number: '111',
105
+ )
106
+ two = Stripe::Invoice.create(
107
+ customer: customer.id,
108
+ currency: 'gbp',
109
+ subscription: subscription.id,
110
+ metadata: {key: 'dos'},
111
+ number: 'two-2',
112
+ receipt_number: '222',
113
+ )
114
+
115
+ response = Stripe::Invoice.search({query: 'currency:"gbp"'}, stripe_version: '2020-08-27')
116
+ expect(response.data.map(&:id)).to match_array([two.id])
117
+
118
+ response = Stripe::Invoice.search({query: %(customer:"#{customer.id}")}, stripe_version: '2020-08-27')
119
+ expect(response.data.map(&:id)).to match_array([one.id, two.id])
120
+
121
+ response = Stripe::Invoice.search({query: 'number:"one-1"'}, stripe_version: '2020-08-27')
122
+ expect(response.data.map(&:id)).to match_array([one.id])
123
+
124
+ response = Stripe::Invoice.search({query: 'receipt_number:"222"'}, stripe_version: '2020-08-27')
125
+ expect(response.data.map(&:id)).to match_array([two.id])
126
+
127
+ response = Stripe::Invoice.search({query: %(subscription:"#{subscription.id}")}, stripe_version: '2020-08-27')
128
+ expect(response.data.map(&:id)).to match_array([one.id, two.id])
129
+
130
+ response = Stripe::Invoice.search({query: 'total:1000'}, stripe_version: '2020-08-27')
131
+ expect(response.data.map(&:id)).to match_array([one.id, two.id])
132
+
133
+ response = Stripe::Invoice.search({query: 'metadata["key"]:"uno"'}, stripe_version: '2020-08-27')
134
+ expect(response.data.map(&:id)).to match_array([one.id])
135
+ end
136
+
137
+ it "respects limit", :aggregate_failures do
138
+ customer = Stripe::Customer.create(email: 'one@one.com', name: 'one', phone: '1111111111', metadata: {key: 'uno'})
139
+ 11.times do
140
+ Stripe::Invoice.create(customer: customer.id, currency: 'usd')
141
+ end
142
+
143
+ response = Stripe::Invoice.search({query: %(customer:"#{customer.id}")}, stripe_version: '2020-08-27')
144
+ expect(response.data.size).to eq(10)
145
+ response = Stripe::Invoice.search({query: %(customer:"#{customer.id}"), limit: 1}, stripe_version: '2020-08-27')
146
+ expect(response.data.size).to eq(1)
147
+ end
148
+
149
+ it "reports search errors", :aggregate_failures do
150
+ expect {
151
+ Stripe::Invoice.search({limit: 1}, stripe_version: '2020-08-27')
152
+ }.to raise_error(Stripe::InvalidRequestError, /Missing required param: query./)
153
+
154
+ expect {
155
+ Stripe::Invoice.search({query: 'asdf'}, stripe_version: '2020-08-27')
156
+ }.to raise_error(Stripe::InvalidRequestError, /We were unable to parse your search query./)
157
+
158
+ expect {
159
+ Stripe::Invoice.search({query: 'foo:"bar"'}, stripe_version: '2020-08-27')
160
+ }.to raise_error(Stripe::InvalidRequestError, /Field `foo` is an unsupported search field for resource `invoices`./)
161
+ end
162
+ end
163
+
82
164
  context "paying an invoice" do
83
165
  before do
84
166
  @invoice = Stripe::Invoice.create
@@ -154,7 +236,10 @@ shared_examples 'Invoice API' do
154
236
  describe 'parameter validation' do
155
237
  it 'fails without parameters' do
156
238
  expect { Stripe::Invoice.upcoming() }.to raise_error {|e|
157
- expect(e).to be_a(ArgumentError) }
239
+ expect(e).to be_a(Stripe::InvalidRequestError)
240
+ expect(e.http_status).to eq(400)
241
+ expect(e.message).to eq('Missing required param: customer if subscription is not provided')
242
+ }
158
243
  end
159
244
 
160
245
  it 'fails without a valid customer' do
@@ -218,4 +218,66 @@ shared_examples 'PaymentIntent API' do
218
218
  expect(e.http_status).to eq(400)
219
219
  }
220
220
  end
221
+
222
+ context "search" do
223
+ # the Search API requires about a minute between writes and reads, so add sleeps accordingly when running live
224
+ it "searches payment intents for exact matches", :aggregate_failures do
225
+ response = Stripe::PaymentIntent.search({query: 'currency:"usd"'}, stripe_version: '2020-08-27')
226
+ expect(response.data.size).to eq(0)
227
+
228
+ customer = Stripe::Customer.create(email: 'johnny@appleseed.com', source: stripe_helper.generate_card_token)
229
+ one = Stripe::PaymentIntent.create(
230
+ amount: 100,
231
+ customer: customer.id,
232
+ currency: 'usd',
233
+ metadata: {key: 'uno'},
234
+ )
235
+ two = Stripe::PaymentIntent.create(
236
+ amount: 3184, # status: requires_action
237
+ customer: customer.id,
238
+ currency: 'gbp',
239
+ metadata: {key: 'dos'},
240
+ )
241
+
242
+ response = Stripe::PaymentIntent.search({query: 'amount:100'}, stripe_version: '2020-08-27')
243
+ expect(response.data.map(&:id)).to match_array([one.id])
244
+
245
+ response = Stripe::PaymentIntent.search({query: 'currency:"gbp"'}, stripe_version: '2020-08-27')
246
+ expect(response.data.map(&:id)).to match_array([two.id])
247
+
248
+ response = Stripe::PaymentIntent.search({query: %(customer:"#{customer.id}")}, stripe_version: '2020-08-27')
249
+ expect(response.data.map(&:id)).to match_array([one.id, two.id])
250
+
251
+ response = Stripe::PaymentIntent.search({query: 'status:"requires_action"'}, stripe_version: '2020-08-27')
252
+ expect(response.data.map(&:id)).to match_array([two.id])
253
+
254
+ response = Stripe::PaymentIntent.search({query: 'metadata["key"]:"uno"'}, stripe_version: '2020-08-27')
255
+ expect(response.data.map(&:id)).to match_array([one.id])
256
+ end
257
+
258
+ it "respects limit", :aggregate_failures do
259
+ 11.times do
260
+ Stripe::PaymentIntent.create(amount: 100, currency: 'usd')
261
+ end
262
+
263
+ response = Stripe::PaymentIntent.search({query: 'amount:100'}, stripe_version: '2020-08-27')
264
+ expect(response.data.size).to eq(10)
265
+ response = Stripe::PaymentIntent.search({query: 'amount:100', limit: 1}, stripe_version: '2020-08-27')
266
+ expect(response.data.size).to eq(1)
267
+ end
268
+
269
+ it "reports search errors", :aggregate_failures do
270
+ expect {
271
+ Stripe::PaymentIntent.search({limit: 1}, stripe_version: '2020-08-27')
272
+ }.to raise_error(Stripe::InvalidRequestError, /Missing required param: query./)
273
+
274
+ expect {
275
+ Stripe::PaymentIntent.search({query: 'asdf'}, stripe_version: '2020-08-27')
276
+ }.to raise_error(Stripe::InvalidRequestError, /We were unable to parse your search query./)
277
+
278
+ expect {
279
+ Stripe::PaymentIntent.search({query: 'foo:"bar"'}, stripe_version: '2020-08-27')
280
+ }.to raise_error(Stripe::InvalidRequestError, /Field `foo` is an unsupported search field for resource `payment_intents`./)
281
+ end
282
+ end
221
283
  end
@@ -128,7 +128,7 @@ shared_examples 'Price API' do
128
128
  expect(two.map &:id).to include('price Two')
129
129
  expect(two.map &:amount).to include(98765)
130
130
  end
131
-
131
+
132
132
  it "retrieves prices filtering by currency" do
133
133
  5.times do | i|
134
134
  stripe_helper.create_price(id: "usd price #{i}", product: product_id, amount: 11, currency: 'usd')
@@ -165,6 +165,75 @@ shared_examples 'Price API' do
165
165
  expect(other_product_prices.all? {|p| p.product == other_product.id }).to be_truthy
166
166
  end
167
167
 
168
+ context "searching prices" do
169
+ # the Search API requires about a minute between writes and reads, so add sleeps accordingly when running live
170
+ it "searches prices for exact matches", :aggregate_failures do
171
+ response = Stripe::Price.search({query: 'currency:"usd"'}, stripe_version: '2020-08-27')
172
+ expect(response.data.size).to eq(0)
173
+
174
+ one = stripe_helper.create_price(
175
+ amount: 100,
176
+ currency: 'usd',
177
+ lookup_key: 'one',
178
+ product: product_id,
179
+ metadata: {key: 'uno'},
180
+ type: "one_time",
181
+ )
182
+ two = stripe_helper.create_price(
183
+ active: false,
184
+ amount: 200,
185
+ currency: 'gbp',
186
+ lookup_key: 'two',
187
+ product: product_id,
188
+ recurring: {interval: 'month'},
189
+ metadata: {key: 'dos'},
190
+ )
191
+
192
+ response = Stripe::Price.search({query: 'active:"true"'}, stripe_version: '2020-08-27')
193
+ expect(response.data.map(&:id)).to match_array([one.id])
194
+
195
+ response = Stripe::Price.search({query: 'currency:"gbp"'}, stripe_version: '2020-08-27')
196
+ expect(response.data.map(&:id)).to match_array([two.id])
197
+
198
+ response = Stripe::Price.search({query: 'lookup_key:"one"'}, stripe_version: '2020-08-27')
199
+ expect(response.data.map(&:id)).to match_array([one.id])
200
+
201
+ response = Stripe::Price.search({query: %(product:"#{product.id}")}, stripe_version: '2020-08-27')
202
+ expect(response.data.map(&:id)).to match_array([one.id, two.id])
203
+
204
+ response = Stripe::Price.search({query: 'type:"recurring"'}, stripe_version: '2020-08-27')
205
+ expect(response.data.map(&:id)).to match_array([two.id])
206
+
207
+ response = Stripe::Price.search({query: 'metadata["key"]:"uno"'}, stripe_version: '2020-08-27')
208
+ expect(response.data.map(&:id)).to match_array([one.id])
209
+ end
210
+
211
+ it "respects limit", :aggregate_failures do
212
+ 11.times do
213
+ stripe_helper.create_price(product: product_id)
214
+ end
215
+
216
+ response = Stripe::Price.search({query: %(product:"#{product.id}")}, stripe_version: '2020-08-27')
217
+ expect(response.data.size).to eq(10)
218
+ response = Stripe::Price.search({query: %(product:"#{product.id}"), limit: 1}, stripe_version: '2020-08-27')
219
+ expect(response.data.size).to eq(1)
220
+ end
221
+
222
+ it "reports search errors", :aggregate_failures do
223
+ expect {
224
+ Stripe::Price.search({limit: 1}, stripe_version: '2020-08-27')
225
+ }.to raise_error(Stripe::InvalidRequestError, /Missing required param: query./)
226
+
227
+ expect {
228
+ Stripe::Price.search({query: 'asdf'}, stripe_version: '2020-08-27')
229
+ }.to raise_error(Stripe::InvalidRequestError, /We were unable to parse your search query./)
230
+
231
+ expect {
232
+ Stripe::Price.search({query: 'foo:"bar"'}, stripe_version: '2020-08-27')
233
+ }.to raise_error(Stripe::InvalidRequestError, /Field `foo` is an unsupported search field for resource `prices`./)
234
+ end
235
+ end
236
+
168
237
  describe "Validations", :live => true do
169
238
  include_context "stripe validator"
170
239
  let(:params) { stripe_helper.create_price_params(product: product_id) }
@@ -85,6 +85,74 @@ shared_examples "Product API" do
85
85
  expect(all.count).to eq(100)
86
86
  end
87
87
 
88
+ context "searching products" do
89
+ # the Search API requires about a minute between writes and reads, so add sleeps accordingly when running live
90
+ it "searches products for exact matches", :aggregate_failures do
91
+ response = Stripe::Product.search({query: 'name:"one"'}, stripe_version: '2020-08-27')
92
+ expect(response.data.size).to eq(0)
93
+
94
+ one = stripe_helper.create_product(
95
+ id: "product_1",
96
+ name: "one",
97
+ description: "un",
98
+ shippable: true,
99
+ url: "http://example.com/one",
100
+ metadata: {key: "uno"},
101
+ )
102
+ two = stripe_helper.create_product(
103
+ id: "product_2",
104
+ name: "two",
105
+ active: false,
106
+ description: "deux",
107
+ url: "http://example.com/two",
108
+ metadata: {key: "dos"},
109
+ )
110
+
111
+ response = Stripe::Product.search({query: 'active:"true"'}, stripe_version: '2020-08-27')
112
+ expect(response.data.map(&:id)).to match_array([one.id])
113
+
114
+ response = Stripe::Product.search({query: 'description:"deux"'}, stripe_version: '2020-08-27')
115
+ expect(response.data.map(&:id)).to match_array([two.id])
116
+
117
+ response = Stripe::Product.search({query: 'name:"one"'}, stripe_version: '2020-08-27')
118
+ expect(response.data.map(&:id)).to match_array([one.id])
119
+
120
+ response = Stripe::Product.search({query: 'shippable:"true"'}, stripe_version: '2020-08-27')
121
+ expect(response.data.map(&:id)).to match_array([one.id])
122
+
123
+ response = Stripe::Product.search({query: 'url:"http://example.com/two"'}, stripe_version: '2020-08-27')
124
+ expect(response.data.map(&:id)).to match_array([two.id])
125
+
126
+ response = Stripe::Product.search({query: 'metadata["key"]:"uno"'}, stripe_version: '2020-08-27')
127
+ expect(response.data.map(&:id)).to match_array([one.id])
128
+ end
129
+
130
+ it "respects limit", :aggregate_failures do
131
+ 11.times do |i|
132
+ stripe_helper.create_product(id: "product_#{i}", name: "Product #{i}")
133
+ end
134
+
135
+ response = Stripe::Product.search({query: 'active:"true"'}, stripe_version: '2020-08-27')
136
+ expect(response.data.size).to eq(10)
137
+ response = Stripe::Product.search({query: 'active:"true"', limit: 1}, stripe_version: '2020-08-27')
138
+ expect(response.data.size).to eq(1)
139
+ end
140
+
141
+ it "reports search errors", :aggregate_failures do
142
+ expect {
143
+ Stripe::Product.search({limit: 1}, stripe_version: '2020-08-27')
144
+ }.to raise_error(Stripe::InvalidRequestError, /Missing required param: query./)
145
+
146
+ expect {
147
+ Stripe::Product.search({query: 'asdf'}, stripe_version: '2020-08-27')
148
+ }.to raise_error(Stripe::InvalidRequestError, /We were unable to parse your search query./)
149
+
150
+ expect {
151
+ Stripe::Product.search({query: 'foo:"bar"'}, stripe_version: '2020-08-27')
152
+ }.to raise_error(Stripe::InvalidRequestError, /Field `foo` is an unsupported search field for resource `products`./)
153
+ end
154
+ end
155
+
88
156
  describe "Validation", :live => true do
89
157
  include_context "stripe validator"
90
158
  let(:params) { stripe_helper.create_product_params }
@@ -687,7 +687,7 @@ shared_examples 'Customer Subscriptions with plans' do
687
687
  customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk)
688
688
 
689
689
  sub = Stripe::Subscription.create({ items: { '0' => { plan: 'silver' } }, customer: customer.id })
690
- sub.delete(at_period_end: true)
690
+ sub.cancel(at_period_end: true)
691
691
 
692
692
  expect(sub.cancel_at_period_end).to be_truthy
693
693
  expect(sub.save).to be_truthy
@@ -752,7 +752,7 @@ shared_examples 'Customer Subscriptions with plans' do
752
752
  customer = Stripe::Customer.create(source: gen_card_tk, plan: plan.id)
753
753
 
754
754
  subscription = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
755
- subscription.delete
755
+ subscription.cancel
756
756
 
757
757
  expect { subscription.save }.to raise_error { |e|
758
758
  expect(e).to be_a(Stripe::InvalidRequestError)
@@ -765,7 +765,7 @@ shared_examples 'Customer Subscriptions with plans' do
765
765
  customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk)
766
766
 
767
767
  sub = Stripe::Subscription.create({ items: [ { plan: plan.id } ], customer: customer.id })
768
- sub.delete(at_period_end: true)
768
+ sub.cancel(at_period_end: true)
769
769
 
770
770
  expect(sub.cancel_at_period_end).to be_truthy
771
771
  expect(sub.save).to be_truthy
@@ -1180,7 +1180,7 @@ shared_examples 'Customer Subscriptions with plans' do
1180
1180
  customer = Stripe::Customer.create(source: gen_card_tk, plan: plan.id)
1181
1181
 
1182
1182
  sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
1183
- result = sub.delete
1183
+ result = sub.cancel
1184
1184
 
1185
1185
  expect(result.status).to eq('canceled')
1186
1186
  expect(result.cancel_at_period_end).to eq false
@@ -1247,7 +1247,7 @@ shared_examples 'Customer Subscriptions with plans' do
1247
1247
  customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: "trial")
1248
1248
 
1249
1249
  sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
1250
- result = sub.delete(at_period_end: true)
1250
+ result = sub.cancel(at_period_end: true)
1251
1251
 
1252
1252
  expect(result.status).to eq('trialing')
1253
1253
 
@@ -1331,7 +1331,7 @@ shared_examples 'Customer Subscriptions with plans' do
1331
1331
  it "does not include canceled subscriptions by default" do
1332
1332
  customer = Stripe::Customer.create(source: gen_card_tk)
1333
1333
  subscription = Stripe::Subscription.create({ plan: plan.id, customer: customer.id })
1334
- subscription.delete
1334
+ subscription.cancel
1335
1335
 
1336
1336
  list = Stripe::Subscription.list({customer: customer.id})
1337
1337
 
@@ -1423,6 +1423,65 @@ shared_examples 'Customer Subscriptions with plans' do
1423
1423
  expect(subscription.items.data[0].metadata.to_h).to eq(foo: 'bar')
1424
1424
  end
1425
1425
  end
1426
+
1427
+ context "search" do
1428
+ # the Search API requires about a minute between writes and reads, so add sleeps accordingly when running live
1429
+ it "searches subscriptions for exact matches", :aggregate_failures do
1430
+ response = Stripe::Subscription.search({query: 'status:"active"'}, stripe_version: '2020-08-27')
1431
+ expect(response.data.size).to eq(0)
1432
+
1433
+ stripe_helper.create_plan(
1434
+ amount: 500,
1435
+ interval: 'month',
1436
+ product: product.id,
1437
+ currency: 'usd',
1438
+ id: 'Sample5'
1439
+ )
1440
+ customer = Stripe::Customer.create(email: 'johnny@appleseed.com', source: gen_card_tk)
1441
+ one = Stripe::Subscription.create(customer: customer.id, items: [{plan: "Sample5"}], metadata: {key: 'uno'})
1442
+ two = Stripe::Subscription.create(customer: customer.id, items: [{plan: "Sample5"}], metadata: {key: 'dos'})
1443
+ Stripe::Subscription.cancel(two.id)
1444
+
1445
+ response = Stripe::Subscription.search({query: 'status:"active"'}, stripe_version: '2020-08-27')
1446
+ expect(response.data.map(&:id)).to match_array([one.id])
1447
+
1448
+ response = Stripe::Subscription.search({query: 'metadata["key"]:"dos"'}, stripe_version: '2020-08-27')
1449
+ expect(response.data.map(&:id)).to match_array([two.id])
1450
+ end
1451
+
1452
+ it "respects limit", :aggregate_failures do
1453
+ stripe_helper.create_plan(
1454
+ amount: 500,
1455
+ interval: 'month',
1456
+ product: product.id,
1457
+ currency: 'usd',
1458
+ id: 'Sample5'
1459
+ )
1460
+ customer = Stripe::Customer.create(email: 'johnny@appleseed.com', source: gen_card_tk)
1461
+ 11.times do
1462
+ Stripe::Subscription.create(customer: customer.id, items: [{plan: "Sample5"}])
1463
+ end
1464
+
1465
+ response = Stripe::Subscription.search({query: 'status:"active"'}, stripe_version: '2020-08-27')
1466
+ expect(response.data.size).to eq(10)
1467
+ response = Stripe::Subscription.search({query: 'status:"active"', limit: 1}, stripe_version: '2020-08-27')
1468
+ expect(response.data.size).to eq(1)
1469
+ end
1470
+
1471
+ it "reports search errors", :aggregate_failures do
1472
+ expect {
1473
+ Stripe::Subscription.search({limit: 1}, stripe_version: '2020-08-27')
1474
+ }.to raise_error(Stripe::InvalidRequestError, /Missing required param: query./)
1475
+
1476
+ expect {
1477
+ Stripe::Subscription.search({query: 'asdf'}, stripe_version: '2020-08-27')
1478
+ }.to raise_error(Stripe::InvalidRequestError, /We were unable to parse your search query./)
1479
+
1480
+ expect {
1481
+ Stripe::Subscription.search({query: 'foo:"bar"'}, stripe_version: '2020-08-27')
1482
+ }.to raise_error(Stripe::InvalidRequestError, /Field `foo` is an unsupported search field for resource `subscriptions`./)
1483
+ end
1484
+ end
1426
1485
  end
1427
1486
 
1428
1487
  shared_examples 'Customer Subscriptions with prices' do
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'set'
2
2
 
3
- gem 'rspec', '~> 3.1'
3
+ gem 'rspec', '~> 3.13'
4
4
  require 'rspec'
5
5
  require 'stripe'
6
6
  require 'stripe_mock'
@@ -22,11 +22,10 @@ Gem::Specification.new do |gem|
22
22
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
23
23
  gem.require_paths = ['lib']
24
24
 
25
- gem.add_dependency 'stripe', '> 5', '< 6'
25
+ gem.add_dependency 'stripe', '> 5', '< 12'
26
26
  gem.add_dependency 'multi_json', '~> 1.0'
27
27
  gem.add_dependency 'dante', '>= 0.2.0'
28
28
 
29
- gem.add_development_dependency 'rspec', '~> 3.7.0'
30
- gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
29
+ gem.add_development_dependency 'rspec', '~> 3.13.0'
31
30
  gem.add_development_dependency 'thin', '~> 1.8.1'
32
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stripe-ruby-mock
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gilbert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-02 00:00:00.000000000 Z
11
+ date: 2024-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: stripe
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '5'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '6'
22
+ version: '12'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '5'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '6'
32
+ version: '12'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: multi_json
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -64,28 +64,14 @@ dependencies:
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: 3.7.0
67
+ version: 3.13.0
68
68
  type: :development
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: 3.7.0
75
- - !ruby/object:Gem::Dependency
76
- name: rubygems-tasks
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '0.2'
82
- type: :development
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '0.2'
74
+ version: 3.13.0
89
75
  - !ruby/object:Gem::Dependency
90
76
  name: thin
91
77
  requirement: !ruby/object:Gem::Requirement
@@ -162,6 +148,7 @@ files:
162
148
  - lib/stripe_mock/request_handlers/helpers/charge_helpers.rb
163
149
  - lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb
164
150
  - lib/stripe_mock/request_handlers/helpers/external_account_helpers.rb
151
+ - lib/stripe_mock/request_handlers/helpers/search_helpers.rb
165
152
  - lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb
166
153
  - lib/stripe_mock/request_handlers/helpers/token_helpers.rb
167
154
  - lib/stripe_mock/request_handlers/invoice_items.rb
@@ -357,7 +344,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
357
344
  - !ruby/object:Gem::Version
358
345
  version: '0'
359
346
  requirements: []
360
- rubygems_version: 3.0.3.1
347
+ rubygems_version: 3.4.19
361
348
  signing_key:
362
349
  specification_version: 4
363
350
  summary: TDD with stripe