quicktravel_client 3.7.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +5 -4
- data/CHANGELOG.md +30 -0
- data/gemfiles/rails6.gemfile +8 -0
- data/lib/quick_travel.rb +2 -0
- data/lib/quick_travel/adapter.rb +13 -25
- data/lib/quick_travel/booking.rb +6 -5
- data/lib/quick_travel/cache.rb +24 -5
- data/lib/quick_travel/checkout.rb +1 -1
- data/lib/quick_travel/client.rb +9 -1
- data/lib/quick_travel/init_from_hash.rb +4 -0
- data/lib/quick_travel/package.rb +13 -0
- data/lib/quick_travel/passenger_type.rb +1 -1
- data/lib/quick_travel/product_configuration.rb +1 -1
- data/lib/quick_travel/products/base.rb +4 -4
- data/lib/quick_travel/reservation.rb +1 -1
- data/lib/quick_travel/resource.rb +1 -1
- data/lib/quick_travel/route.rb +1 -1
- data/lib/quick_travel/route_stop.rb +8 -1
- data/lib/quick_travel/vehicle_type.rb +1 -1
- data/lib/quick_travel/version.rb +1 -1
- data/quicktravel_client.gemspec +5 -5
- data/spec/adapter_spec.rb +34 -3
- data/spec/booking_spec.rb +10 -0
- data/spec/checkout_spec.rb +0 -182
- data/spec/clients_spec.rb +42 -0
- data/spec/discounts_spec.rb +21 -21
- data/spec/package_spec.rb +24 -0
- data/spec/passenger_type_spec.rb +1 -1
- data/spec/product_configuration_spec.rb +11 -0
- data/spec/reservation_spec.rb +20 -0
- data/spec/spec_helper.rb +6 -3
- data/spec/support/cassettes/accommodation_reserve.yml +12 -4
- data/spec/support/cassettes/basic_product_scheduled_trips.yml +3 -1
- data/spec/support/cassettes/basic_product_scheduled_trips_multi_sector.yml +3 -1
- data/spec/support/cassettes/basic_product_scheduled_trips_unbookable.yml +3 -1
- data/spec/support/cassettes/booking_activate.yml +6 -2
- data/spec/support/cassettes/booking_cancel.yml +6 -2
- data/spec/support/cassettes/booking_create.yml +3 -1
- data/spec/support/cassettes/booking_create_accommodation.yml +3 -1
- data/spec/support/cassettes/booking_documents.yml +3 -1
- data/spec/support/cassettes/booking_non_existant.yml +3 -1
- data/spec/support/cassettes/booking_price_changes.yml +3 -1
- data/spec/support/cassettes/booking_show.yml +3 -1
- data/spec/support/cassettes/booking_update.yml +6 -2
- data/spec/support/cassettes/booking_with_comments.yml +119 -0
- data/spec/support/cassettes/booking_with_documents.yml +6 -2
- data/spec/support/cassettes/booking_with_nested_attributes.yml +9 -3
- data/spec/support/cassettes/booking_with_price_changes.yml +3 -1
- data/spec/support/cassettes/checkout_client_token.yml +3 -1
- data/spec/support/cassettes/client_templates.yml +120 -0
- data/spec/support/cassettes/countries.yml +3 -1
- data/spec/support/cassettes/country_all.yml +3 -1
- data/spec/support/cassettes/create_reservation_fail.yml +3 -1
- data/spec/support/cassettes/create_reservation_with_booking.yml +3 -1
- data/spec/support/cassettes/locations.yml +3 -1
- data/spec/support/cassettes/opal_modern_pay_failed_booking.yml +3 -1
- data/spec/support/cassettes/opal_modern_pay_failed_create.yml +3 -1
- data/spec/support/cassettes/opal_modern_pay_failed_update.yml +3 -1
- data/spec/support/cassettes/opal_modern_pay_successful_booking.yml +3 -1
- data/spec/support/cassettes/opal_modern_pay_successful_response.yml +3 -1
- data/spec/support/cassettes/opal_modern_pay_successful_update_response.yml +3 -1
- data/spec/support/cassettes/opal_pay.yml +3 -1
- data/spec/support/cassettes/opal_pay_booking.yml +3 -1
- data/spec/support/cassettes/package_show.yml +83 -0
- data/spec/support/cassettes/package_show_product_type.yml +80 -0
- data/spec/support/cassettes/passenger_all.yml +3 -1
- data/spec/support/cassettes/payment_info.yml +3 -1
- data/spec/support/cassettes/price_quote.yml +6 -2
- data/spec/support/cassettes/product_date_range_bookability.yml +3 -1
- data/spec/support/cassettes/product_show.yml +3 -1
- data/spec/support/cassettes/product_show_as_agent.yml +3 -1
- data/spec/support/cassettes/product_type_all.yml +3 -1
- data/spec/support/cassettes/product_type_resource_categories.yml +3 -1
- data/spec/support/cassettes/product_type_resource_categories_tickets.yml +3 -1
- data/spec/support/cassettes/product_type_routes.yml +3 -1
- data/spec/support/cassettes/property.yml +3 -1
- data/spec/support/cassettes/property_types.yml +3 -1
- data/spec/support/cassettes/region_show.yml +3 -1
- data/spec/support/cassettes/reservation_resource.yml +3 -1
- data/spec/support/cassettes/reservation_with_extra_picks.yml +9 -3
- data/spec/support/cassettes/resource_category_all.yml +3 -1
- data/spec/support/cassettes/resource_category_all_for_product_type_8.yml +3 -1
- data/spec/support/cassettes/resource_fare_bases.yml +3 -1
- data/spec/support/cassettes/resource_show.yml +3 -1
- data/spec/support/cassettes/resource_with_price.yml +3 -1
- data/spec/support/cassettes/settings_basic.yml +3 -1
- data/spec/support/cassettes/tenant_switcher.yml +6 -2
- data/spec/support/cassettes/wrong_url.yml +3 -1
- data/spec/support/coverage_loader.rb +1 -1
- metadata +35 -29
- data/gemfiles/rails4.gemfile +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1bba05a60170b4b63f097183048b5c1bc8c73192631268c47bad3bf75999851c
|
4
|
+
data.tar.gz: 637a0c94cd80217ddbe580c77ad5ef6ac2ef99d1465c870762f1686660967fcb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 295a00c7ed151281f4a406fea28804ad3318f55ba998350c8dd887666dc11f79038e0c381bc16e9f9f8bc2dfb07cc6fd3085ebeea02f9fa3ae4fa84f26926a38
|
7
|
+
data.tar.gz: aee796df5056e802266ebe1962ca9b882992cd8c77066ec27c97e0b36ae045ad2827485b19f8893dac75a61fe3f6a692e0d8fa4af751b4173b442c8a1e1e1ee0
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.7.1
|
data/.travis.yml
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.2
|
4
|
-
- 2.3
|
5
|
-
- 2.4
|
6
3
|
- 2.5
|
4
|
+
- 2.6
|
5
|
+
- 2.7
|
6
|
+
before_install:
|
7
|
+
- gem install bundler
|
7
8
|
script: bundle && bundle exec rake spec
|
8
9
|
gemfile:
|
9
|
-
- gemfiles/rails4.gemfile
|
10
10
|
- gemfiles/rails5.gemfile
|
11
|
+
- gemfiles/rails6.gemfile
|
11
12
|
notifications:
|
12
13
|
email:
|
13
14
|
- support@travellink.com.au
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,36 @@ All notable changes to this project will be documented in this file.
|
|
3
3
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
4
4
|
This changelog adheres to [Keep a CHANGELOG](http://keepachangelog.com/).
|
5
5
|
|
6
|
+
## Unreleased
|
7
|
+
|
8
|
+
## [4.1.0]
|
9
|
+
### Added
|
10
|
+
- [TT-7788] Add API namespace to vehicle_types endpoint
|
11
|
+
|
12
|
+
## [4.0.0]
|
13
|
+
- [TT-7385] Update Money dependency, test against Ruby 2.7 / Rails 6
|
14
|
+
|
15
|
+
## [3.9.0]
|
16
|
+
### Added
|
17
|
+
- [DC-3115] Add customer comments method in booking
|
18
|
+
- [DC-2942] Add package class to support quantity based package
|
19
|
+
|
20
|
+
## [3.8.1]
|
21
|
+
### Changed
|
22
|
+
- [DC-3033] Reverse changes in checkout class to fix polipay redirection in EcomEngine
|
23
|
+
|
24
|
+
## [3.8.0]
|
25
|
+
### Added
|
26
|
+
- [DC-1794] Update httparty to allow caching the whole response, also add namespace to cache key
|
27
|
+
- [DC-1418] Port NRMA portal availability cache back to EcomEngine
|
28
|
+
- [TT-4850] Added client templates
|
29
|
+
- [DC-1692] Fix error that can be thrown when checking if a product configuration can be priced
|
30
|
+
- [TT-6246] Remove Booking.delete_reservations method
|
31
|
+
|
32
|
+
### Changed
|
33
|
+
- [DC-2997] Remove API key from body, and move it to header
|
34
|
+
- [DC-1767] include long/lat changes to Stop
|
35
|
+
|
6
36
|
## [3.7.0]
|
7
37
|
### Added
|
8
38
|
- [DC-1437] Add relationship accesssor methods
|
data/lib/quick_travel.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
#
|
3
3
|
module QuickTravel
|
4
4
|
require 'active_support' # for .try, etc.
|
5
|
+
require 'money_extensions'
|
5
6
|
|
6
7
|
require 'quick_travel/cache'
|
7
8
|
require 'quick_travel/config'
|
@@ -33,6 +34,7 @@ module QuickTravel
|
|
33
34
|
require 'quick_travel/drop_off_location'
|
34
35
|
require 'quick_travel/drop_off_option'
|
35
36
|
require 'quick_travel/location'
|
37
|
+
require 'quick_travel/package'
|
36
38
|
require 'quick_travel/party'
|
37
39
|
require 'quick_travel/passenger'
|
38
40
|
require 'quick_travel/passenger_type'
|
data/lib/quick_travel/adapter.rb
CHANGED
@@ -65,7 +65,7 @@ module QuickTravel
|
|
65
65
|
def self.all(opts = {})
|
66
66
|
if lookup
|
67
67
|
cache_name = ["#{name}.all-attrs", opts.to_param].reject(&:blank?).join('?')
|
68
|
-
find_all!("#{api_base}.json", opts.merge(
|
68
|
+
find_all!("#{api_base}.json", opts.merge(cache_key: cache_name, cache_options: { disable_namespacing: true }))
|
69
69
|
else
|
70
70
|
find_all!("#{api_base}.json", opts)
|
71
71
|
end
|
@@ -80,10 +80,6 @@ module QuickTravel
|
|
80
80
|
put_and_validate("#{api_base}/#{id}.json", options)
|
81
81
|
end
|
82
82
|
|
83
|
-
def to_hash
|
84
|
-
instance_values
|
85
|
-
end
|
86
|
-
|
87
83
|
def to_s
|
88
84
|
if defined? @to_s
|
89
85
|
@to_s
|
@@ -102,20 +98,14 @@ module QuickTravel
|
|
102
98
|
end
|
103
99
|
|
104
100
|
def self.find_all!(request_path, opts = {})
|
105
|
-
response =
|
106
|
-
|
107
|
-
|
108
|
-
}
|
109
|
-
else
|
110
|
-
get_and_validate(request_path, opts, return_response_object: true)
|
111
|
-
end
|
112
|
-
full_response = response.respond_to? :parsed_response
|
113
|
-
parsed_response = full_response ? response.parsed_response : response
|
101
|
+
response = QuickTravel::Cache.cache(opts[:cache_key], opts[:cache_options]) {
|
102
|
+
get_and_validate(request_path, opts.except(:cache_key, :cache_options), return_response_object: true)
|
103
|
+
}
|
114
104
|
|
115
|
-
deserializer = Deserializer.new(parsed_response)
|
105
|
+
deserializer = Deserializer.new(response.parsed_response)
|
116
106
|
objects = Array.wrap(deserializer.extract_under_root(self))
|
117
107
|
|
118
|
-
if
|
108
|
+
if response.headers['pagination'].present?
|
119
109
|
pagination_headers = ::JSON.parse(response.headers['pagination'])
|
120
110
|
WillPaginate::Collection.create(pagination_headers['current_page'], pagination_headers['per_page'], pagination_headers['total_entries']) do |pager|
|
121
111
|
pager.replace(objects)
|
@@ -202,7 +192,11 @@ module QuickTravel
|
|
202
192
|
end
|
203
193
|
|
204
194
|
def self.call_and_validate(http_method, path, query = {}, opts = {})
|
205
|
-
|
195
|
+
response = QuickTravel::Cache.cache(opts[:cache_key], opts[:cache_options]) {
|
196
|
+
response_object = Api.call_and_validate(http_method, path, query, opts.except(:cache_key, :cache_options))
|
197
|
+
response_object = response_object.parsed_response if !opts[:cache_key] and !opts[:return_response_object]
|
198
|
+
response_object
|
199
|
+
}
|
206
200
|
end
|
207
201
|
|
208
202
|
def self.base_uri(uri = nil)
|
@@ -215,12 +209,11 @@ module QuickTravel
|
|
215
209
|
|
216
210
|
def self.call_and_validate(http_method, path, query = {}, opts = {})
|
217
211
|
http_params = opts.clone
|
218
|
-
return_response_object = http_params.delete(:return_response_object)
|
219
|
-
|
220
212
|
# Set default token
|
221
213
|
http_params[:query] ||= FilterQuery.new(query).call
|
222
214
|
http_params[:headers] ||= {}
|
223
215
|
http_params[:headers]['Content-length'] = '0' if http_params[:body].blank?
|
216
|
+
http_params[:headers]['x-api-key'] = QuickTravel.config.access_key
|
224
217
|
expect = http_params.delete(:expect)
|
225
218
|
|
226
219
|
# Use :body instead of :query for put/post.
|
@@ -230,7 +223,6 @@ module QuickTravel
|
|
230
223
|
if [:put, :post].include?(http_method.to_sym)
|
231
224
|
http_params[:body].merge!(http_params.delete(:query))
|
232
225
|
end
|
233
|
-
http_params[:body][:access_key] = QuickTravel.config.access_key
|
234
226
|
http_params[:follow_redirects] = false
|
235
227
|
|
236
228
|
begin
|
@@ -256,11 +248,7 @@ module QuickTravel
|
|
256
248
|
|
257
249
|
validate!(response)
|
258
250
|
|
259
|
-
|
260
|
-
response
|
261
|
-
else
|
262
|
-
response.parsed_response
|
263
|
-
end
|
251
|
+
response
|
264
252
|
end
|
265
253
|
|
266
254
|
# Do standard validations on response
|
data/lib/quick_travel/booking.rb
CHANGED
@@ -13,7 +13,7 @@ module QuickTravel
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.find_by_reference(reference)
|
16
|
-
find_all!("#{api_base}/reference/#{URI.
|
16
|
+
find_all!("#{api_base}/reference/#{URI.encode_www_form_component(reference)}.json").first
|
17
17
|
end
|
18
18
|
|
19
19
|
def documents(regenerate = false)
|
@@ -157,10 +157,6 @@ module QuickTravel
|
|
157
157
|
reserve(:packages, options)
|
158
158
|
end
|
159
159
|
|
160
|
-
def delete_reservations
|
161
|
-
delete_and_validate("#{api_base}/#{@id}/reservations")
|
162
|
-
end
|
163
|
-
|
164
160
|
# Delete a reservation
|
165
161
|
#
|
166
162
|
# Returns current booking object after deleting the reservation
|
@@ -300,6 +296,11 @@ module QuickTravel
|
|
300
296
|
Encrypt.access_key(@id.to_s)
|
301
297
|
end
|
302
298
|
|
299
|
+
def customer_comments
|
300
|
+
comment = comments.detect{ |comment| comment['comment_type'] == 'customer' }
|
301
|
+
comment.presence.try(:[], 'text') || ''
|
302
|
+
end
|
303
|
+
|
303
304
|
protected
|
304
305
|
|
305
306
|
def reserve(url, options)
|
data/lib/quick_travel/cache.rb
CHANGED
@@ -6,16 +6,27 @@ module QuickTravel
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
-
def self.cache(key, cache_options =
|
9
|
+
def self.cache(key, cache_options = nil)
|
10
|
+
return yield unless key.present?
|
11
|
+
cache_options ||= {}
|
12
|
+
key = "#{@@namespace}_#{key}" unless cache_options[:disable_namespacing]
|
10
13
|
cached_value = cache_store.read(key)
|
11
|
-
return cached_value unless cached_value
|
14
|
+
return cached_value unless cache_empty?(cached_value)
|
12
15
|
return nil unless block_given?
|
13
16
|
cache_options ||= {}
|
14
17
|
cache_options[:expires_in] = 1.day unless cache_options.key?(:expires_in)
|
15
18
|
yield.tap { |value| cache_store.write(key, value, cache_options) }
|
16
19
|
end
|
17
20
|
|
18
|
-
def self.
|
21
|
+
def self.cache_empty?(cached_value)
|
22
|
+
if cached_value.respond_to?(:body)
|
23
|
+
return cached_value.body.nil? || cached_value.body.empty?
|
24
|
+
end
|
25
|
+
cached_value.nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.delete(key, namespace = true)
|
29
|
+
key = "#{@@namespace}_#{key}" if namespace
|
19
30
|
cache_store.delete(key)
|
20
31
|
end
|
21
32
|
|
@@ -27,8 +38,16 @@ module QuickTravel
|
|
27
38
|
@@cache_store
|
28
39
|
end
|
29
40
|
|
30
|
-
def self.cache_store=(
|
31
|
-
@@cache_store =
|
41
|
+
def self.cache_store=(session)
|
42
|
+
@@cache_store = session
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.namespace
|
46
|
+
@@namespace
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.namespace=(namespace)
|
50
|
+
@@namespace = namespace
|
32
51
|
end
|
33
52
|
end
|
34
53
|
end
|
@@ -46,7 +46,7 @@ module QuickTravel
|
|
46
46
|
# TODO Move to an external builder?
|
47
47
|
def self.attributes_for
|
48
48
|
attrs = yield
|
49
|
-
attrs[:completed] = attrs['progress'] == 'completed'
|
49
|
+
attrs[:completed] = attrs['progress'] == 'completed'
|
50
50
|
attrs[:successful] = attrs[:completed]
|
51
51
|
attrs
|
52
52
|
rescue AdapterError => e
|
data/lib/quick_travel/client.rb
CHANGED
@@ -1,7 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'quick_travel/adapter'
|
1
4
|
require 'quick_travel/init_from_hash'
|
2
5
|
|
3
6
|
module QuickTravel
|
4
|
-
class Client
|
7
|
+
class Client < Adapter
|
5
8
|
include QuickTravel::InitFromHash
|
9
|
+
self.api_base = '/api/clients'
|
10
|
+
|
11
|
+
def templates
|
12
|
+
get_and_validate("/api/clients/#{id}/templates")
|
13
|
+
end
|
6
14
|
end
|
7
15
|
end
|
@@ -13,7 +13,7 @@ module QuickTravel
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.pluralize(count, singular, plural = nil)
|
16
|
-
"#{count || 0} " + ((count == 1
|
16
|
+
"#{count || 0} " + ((count == 1) ? singular : (plural || singular.pluralize))
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -7,13 +7,13 @@ module QuickTravel
|
|
7
7
|
bookable || exception_type == 'inventory'
|
8
8
|
end
|
9
9
|
|
10
|
-
def self.find(search_params = {})
|
11
|
-
find_for_type(@reservation_for_type, search_params)
|
10
|
+
def self.find(search_params = {}, opts = {})
|
11
|
+
find_for_type(@reservation_for_type, search_params, opts)
|
12
12
|
end
|
13
13
|
|
14
|
-
def self.find_for_type(type, search_params = {})
|
14
|
+
def self.find_for_type(type, search_params = {}, opts = {})
|
15
15
|
url = "/reservation_for/#{type}/find_services_for.json"
|
16
|
-
product_maps = post_and_validate(url, search_params)
|
16
|
+
product_maps = post_and_validate(url, search_params, opts)
|
17
17
|
product_maps.map { |product_map| new(product_map) }
|
18
18
|
end
|
19
19
|
end
|
@@ -42,7 +42,7 @@ module QuickTravel
|
|
42
42
|
passenger_type_count = {}
|
43
43
|
if passenger_splits.present?
|
44
44
|
passenger_splits.each do |p|
|
45
|
-
passenger = booking.find_passenger_by_id(p
|
45
|
+
passenger = booking.find_passenger_by_id(p.consumer_id)
|
46
46
|
|
47
47
|
if passenger.present?
|
48
48
|
passenger_type_count[passenger.passenger_type_id] ||= 0
|
@@ -13,7 +13,7 @@ module QuickTravel
|
|
13
13
|
|
14
14
|
def self.all_with_price(opts)
|
15
15
|
cache_key = GenerateCacheKey.new(name, opts).call
|
16
|
-
find_all!("/api/resources/index_with_price.json", opts.merge(
|
16
|
+
find_all!("/api/resources/index_with_price.json", opts.merge(cache_key: cache_key))
|
17
17
|
end
|
18
18
|
|
19
19
|
def product_type
|
data/lib/quick_travel/route.rb
CHANGED
@@ -17,7 +17,7 @@ module QuickTravel
|
|
17
17
|
# All routes for a given product type
|
18
18
|
def self.all(product_type_id)
|
19
19
|
find_all!("/product_types/#{product_type_id}/routes.json",
|
20
|
-
|
20
|
+
cache_key: "QuickTravel::Route.all-#{product_type_id}-attrs")
|
21
21
|
end
|
22
22
|
|
23
23
|
def self.find(routes_list, route_id)
|
@@ -5,7 +5,14 @@ module QuickTravel
|
|
5
5
|
include QuickTravel::InitFromHash
|
6
6
|
|
7
7
|
def stop
|
8
|
-
Stop.new({
|
8
|
+
Stop.new({
|
9
|
+
id: stop_id,
|
10
|
+
name: name,
|
11
|
+
code: code,
|
12
|
+
address: address,
|
13
|
+
longitude: longitude,
|
14
|
+
latitude: latitude
|
15
|
+
})
|
9
16
|
end
|
10
17
|
end
|
11
18
|
|
data/lib/quick_travel/version.rb
CHANGED
data/quicktravel_client.gemspec
CHANGED
@@ -16,14 +16,14 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
17
|
spec.require_paths = ['lib']
|
18
18
|
|
19
|
-
spec.add_dependency 'httparty'
|
20
|
-
spec.add_dependency '
|
21
|
-
spec.add_dependency 'activesupport', '>= 2.0.0'
|
19
|
+
spec.add_dependency 'httparty'
|
20
|
+
spec.add_dependency 'activesupport', '>= 5.0.0'
|
22
21
|
spec.add_dependency 'facets'
|
23
|
-
spec.add_dependency 'money', '>=
|
22
|
+
spec.add_dependency 'money', '>= 6.0'
|
23
|
+
spec.add_dependency 'money_extensions', '>= 1.0'
|
24
24
|
spec.add_dependency 'will_paginate'
|
25
25
|
|
26
|
-
spec.add_development_dependency 'bundler', '~>
|
26
|
+
spec.add_development_dependency 'bundler', '~> 2'
|
27
27
|
spec.add_development_dependency 'rake'
|
28
28
|
spec.add_development_dependency 'rspec'
|
29
29
|
spec.add_development_dependency 'rspec-its'
|