diff --git a/CHANGES.md b/CHANGES.md index 9ecf071e..42b74aa0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,9 @@ +# 7.7.2 + +* Fixes bug with auto-pagination for Numbers. See PR [#236](https://github.com/Vonage/vonage-ruby-sdk/pull/236). + +* Adds support for `PATCH` requests to be passed to the `Logger#log_request_info` method. See PR [#237](https://github.com/Vonage/vonage-ruby-sdk/pull/237). + # 7.7.1 * Adds support for `PATCH` requests to be passed to the `JSON::update` method See PR [#230](https://github.com/Vonage/vonage-ruby-sdk/pull/230). diff --git a/lib/vonage/logger.rb b/lib/vonage/logger.rb index b29fc810..be48a5ff 100644 --- a/lib/vonage/logger.rb +++ b/lib/vonage/logger.rb @@ -18,7 +18,7 @@ def initialize(logger) def_delegator :@logger, name, name end - sig { params(request: T.any(Net::HTTP::Post, Net::HTTP::Get, Net::HTTP::Delete, Net::HTTP::Put)).void } + sig { params(request: T.any(Net::HTTP::Post, Net::HTTP::Get, Net::HTTP::Delete, Net::HTTP::Put, Net::HTTP::Patch)).void } def log_request_info(request) @logger = T.let(@logger, T.nilable(T.any(::Logger, Vonage::Logger))) diff --git a/lib/vonage/namespace.rb b/lib/vonage/namespace.rb index 4b5cebec..369f200a 100644 --- a/lib/vonage/namespace.rb +++ b/lib/vonage/namespace.rb @@ -109,7 +109,7 @@ def request(path, params: nil, type: Get, response_class: Response, &block) response = make_request!(request, &block) if auto_advance - iterable_request(path, response: response, response_class: response_class, &block) + iterable_request(path, response: response, response_class: response_class, params: params, &block) else return if block @@ -117,7 +117,7 @@ def request(path, params: nil, type: Get, response_class: Response, &block) end end - def iterable_request(path, response: nil, response_class: nil, &block) + def iterable_request(path, response: nil, response_class: nil, params: {}, &block) json_response = ::JSON.parse(response.body) response = parse(response, response_class) remainder = remaining_count(json_response) diff --git a/lib/vonage/numbers.rb b/lib/vonage/numbers.rb index 1a134fc4..08c86293 100644 --- a/lib/vonage/numbers.rb +++ b/lib/vonage/numbers.rb @@ -40,11 +40,11 @@ class Numbers < Namespace # # @option params [Integer] :index # Page index. - # + # # @option params [Boolean] :auto_advance # Set this to `true` to auto-advance through all the pages in the record # and collect all the data. The default is `false`. - # + # # @param [Hash] params # # @return [ListResponse] @@ -92,7 +92,7 @@ def list(params = nil) # @option params [Boolean] :auto_advance # Set this to `true` to auto-advance through all the pages in the record # and collect all the data. The default is `false`. - # + # # @param [Hash] params # # @return [ListResponse] @@ -200,5 +200,29 @@ def cancel(params) def update(params) request('/number/update', params: camelcase(params), type: Post, response_class: Response) end + + private + + # A specific implementation of iterable_request for Numbers, because the Numbers API + # handles pagination differently to other Vonage APIs + def iterable_request(path, response: nil, response_class: nil, params: {}, &block) + response = parse(response, response_class) + params[:index] = 1 unless params.has_key?(:index) + size = params.fetch(:size, 10) + count_from_index = response[:count] - ((params[:index] - 1) * size) + + while count_from_index > response.numbers.size + params[:index] += 1 + request = build_request(path: path, type: Get, params: params) + + # Make request... + paginated_response = make_request!(request) + next_response = parse(paginated_response, response_class) + + response.numbers.push(*next_response.numbers) + end + + response + end end end diff --git a/lib/vonage/version.rb b/lib/vonage/version.rb index 4984df1c..47b0c1ed 100644 --- a/lib/vonage/version.rb +++ b/lib/vonage/version.rb @@ -1,5 +1,5 @@ # typed: strong module Vonage - VERSION = '7.7.1' + VERSION = '7.7.2' end diff --git a/test/vonage/numbers_test.rb b/test/vonage/numbers_test.rb index be855bf8..fbd21323 100644 --- a/test/vonage/numbers_test.rb +++ b/test/vonage/numbers_test.rb @@ -38,6 +38,34 @@ def test_search_method assert_kind_of Vonage::Numbers::ListResponse, numbers.search(params) end + def test_search_method_with_auto_advance + uri = 'https://rest.nexmo.com/number/search' + + params = {country: country} + + stub_request(:get, uri).with(query: params.merge(api_key_and_secret)).to_return(numbers_response_paginated_page_1) + + stub_request(:get, uri).with(query: params.merge(api_key_and_secret.merge(index: 2))).to_return(numbers_response_paginated_page_2) + + response = numbers.search(params.merge(auto_advance: true)) + + assert_kind_of Vonage::Numbers::ListResponse, response + assert_equal 14, response.numbers.length + end + + def test_search_method_with_auto_advance_with_index_offset_by_one_page + uri = 'https://rest.nexmo.com/number/search' + + params = {country: country} + + stub_request(:get, uri).with(query: params.merge(api_key_and_secret.merge(index: 2))).to_return(numbers_response_paginated_page_2) + + response = numbers.search(params.merge(auto_advance: true, index: 2)) + + assert_kind_of Vonage::Numbers::ListResponse, response + assert_equal 4, response.numbers.length + end + def test_buy_method uri = 'https://rest.nexmo.com/number/buy' diff --git a/test/vonage/test.rb b/test/vonage/test.rb index 351c2a8b..dc3f0663 100644 --- a/test/vonage/test.rb +++ b/test/vonage/test.rb @@ -96,28 +96,204 @@ def request(body: nil, query: nil, headers: {}) def voice_response { - body: '{"_embedded": {"calls":[]}}', + body: '{"_embedded": {"calls":[]}}', headers: response_headers } end def applications_response { - body: '{"_embedded": {"applications":[]}}', + body: '{"_embedded": {"applications":[]}}', headers: response_headers } end def secrets_response { - body: '{"_embedded": {"secrets":[]}}', + body: '{"_embedded": {"secrets":[]}}', headers: response_headers } end def numbers_response { - body: '{"numbers":[]}', + body: '{"numbers":[]}', + headers: response_headers + } + end + + def numbers_response_paginated_page_1 + { + body: '{ + "count": 14, + "numbers":[ + { + "country": "GB", + "msisdn": "447700900000", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + }, + { + "country": "GB", + "msisdn": "447700900001", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + }, + { + "country": "GB", + "msisdn": "447700900002", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + }, + { + "country": "GB", + "msisdn": "447700900003", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + }, + { + "country": "GB", + "msisdn": "447700900004", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + }, + { + "country": "GB", + "msisdn": "447700900005", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + }, + { + "country": "GB", + "msisdn": "447700900006", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + }, + { + "country": "GB", + "msisdn": "447700900007", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + }, + { + "country": "GB", + "msisdn": "447700900008", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + }, + { + "country": "GB", + "msisdn": "447700900009", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + } + ] + }', + headers: response_headers + } + end + + def numbers_response_paginated_page_2 + { + body: '{ + "count": 14, + "numbers":[ + { + "country": "GB", + "msisdn": "447700900010", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + }, + { + "country": "GB", + "msisdn": "447700900011", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + }, + { + "country": "GB", + "msisdn": "447700900012", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + }, + { + "country": "GB", + "msisdn": "447700900013", + "type": "mobile-lvn", + "cost": "1.25", + "features": [ + "VOICE", + "SMS", + "MMS" + ] + } + ] + }', headers: response_headers } end