ideal_postcodes 0.1.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +6 -0
- data/README.md +295 -42
- data/Rakefile +13 -6
- data/ideal-postcodes-ruby.gemspec +9 -10
- data/lib/idealpostcodes.rb +30 -9
- data/lib/idealpostcodes/address.rb +31 -0
- data/lib/idealpostcodes/key.rb +13 -0
- data/lib/idealpostcodes/postcode.rb +11 -24
- data/lib/idealpostcodes/util.rb +2 -2
- data/lib/idealpostcodes/version.rb +1 -1
- data/spec/addresses_spec.rb +68 -0
- data/spec/idealpostcodes_spec.rb +56 -0
- data/spec/keys_spec.rb +25 -0
- data/spec/postcodes_spec.rb +66 -0
- data/spec/spec_helper.rb +65 -0
- data/spec/vcr_cassettes/IdealPostcodes_Address_lookup_raises_an_exception_if_invalid_key.yml +42 -0
- data/spec/vcr_cassettes/IdealPostcodes_Address_lookup_raises_an_exception_if_limit_breached.yml +42 -0
- data/spec/vcr_cassettes/IdealPostcodes_Address_lookup_raises_an_exception_if_no_lookups_remaining.yml +42 -0
- data/spec/vcr_cassettes/IdealPostcodes_Address_lookup_returns_an_address_for_a_valid_UDPRN.yml +74 -0
- data/spec/vcr_cassettes/IdealPostcodes_Address_lookup_returns_nil_for_an_invalid_UDPRN.yml +42 -0
- data/spec/vcr_cassettes/IdealPostcodes_Address_search_is_sensitive_to_limit.yml +81 -0
- data/spec/vcr_cassettes/IdealPostcodes_Address_search_is_sensitive_to_page.yml +369 -0
- data/spec/vcr_cassettes/IdealPostcodes_Address_search_raises_an_exception_if_invalid_key.yml +42 -0
- data/spec/vcr_cassettes/IdealPostcodes_Address_search_raises_an_exception_if_limit_breached.yml +42 -0
- data/spec/vcr_cassettes/IdealPostcodes_Address_search_raises_an_exception_if_no_lookups_remaining.yml +42 -0
- data/spec/vcr_cassettes/IdealPostcodes_Address_search_returns_results_in_a_SearchResult_object.yml +273 -0
- data/spec/vcr_cassettes/IdealPostcodes_Key_lookup_details_returns_key_details.yml +62 -0
- data/spec/vcr_cassettes/IdealPostcodes_Key_lookup_returns_the_availability_status_of_a_key_false_key_.yml +45 -0
- data/spec/vcr_cassettes/IdealPostcodes_Key_lookup_returns_the_availability_status_of_a_key_true_key_.yml +45 -0
- data/spec/vcr_cassettes/IdealPostcodes_Postcode_find_by_location_is_sensitive_to_limit_parameter.yml +52 -0
- data/spec/vcr_cassettes/IdealPostcodes_Postcode_find_by_location_is_sensitive_to_radius_parament.yml +133 -0
- data/spec/vcr_cassettes/IdealPostcodes_Postcode_find_by_location_returns_an_array_of_postcodes_and_locations.yml +84 -0
- data/spec/vcr_cassettes/IdealPostcodes_Postcode_find_by_location_returns_an_empty_array_if_no_results_are_found.yml +43 -0
- data/spec/vcr_cassettes/IdealPostcodes_Postcode_lookup_raises_an_exception_if_invalid_key.yml +42 -0
- data/spec/vcr_cassettes/IdealPostcodes_Postcode_lookup_raises_an_exception_if_key_has_run_out_of_balance.yml +42 -0
- data/spec/vcr_cassettes/IdealPostcodes_Postcode_lookup_raises_an_exception_if_limit_has_been_reached.yml +42 -0
- data/spec/vcr_cassettes/IdealPostcodes_Postcode_lookup_returns_a_list_of_addresses_for_a_postcode.yml +268 -0
- data/spec/vcr_cassettes/IdealPostcodes_Postcode_lookup_returns_an_empty_array_if_postcode_does_not_exist.yml +42 -0
- data/spec/vcr_cassettes/IdealPostcodes_key_available_returns_false_if_key_is_unavailable.yml +45 -0
- data/spec/vcr_cassettes/IdealPostcodes_key_available_returns_true_if_key_is_available.yml +45 -0
- data/spec/vcr_cassettes/IdealPostcodes_key_details_raises_an_exception_if_no_secret_is_provided.yml +45 -0
- data/spec/vcr_cassettes/IdealPostcodes_key_details_returns_key_information.yml +62 -0
- data/spec/vcr_cassettes/IdealPostcodes_request_generates_a_HTTP_request.yml +268 -0
- data/spec/vcr_cassettes/IdealPostcodes_request_raises_authentication_error_if_invalid_key_is_provided.yml +42 -0
- data/spec/vcr_cassettes/IdealPostcodes_request_raises_limit_reached_error_if_a_limit_has_been_breached.yml +42 -0
- data/spec/vcr_cassettes/IdealPostcodes_request_raises_token_exhausted_error_if_key_balance_is_depleted.yml +42 -0
- metadata +96 -39
- data/test/test_helper.rb +0 -77
- data/test/test_ideal_postcodes.rb +0 -78
    
        data/lib/idealpostcodes.rb
    CHANGED
    
    | @@ -1,18 +1,24 @@ | |
| 1 | 
            -
            require 'rest-client'
         | 
| 2 | 
            -
            require 'uri'
         | 
| 3 | 
            -
            require 'multi_json'
         | 
| 4 1 | 
             
            require 'cgi'
         | 
| 2 | 
            +
            require 'uri'
         | 
| 3 | 
            +
            require 'json'
         | 
| 4 | 
            +
            require 'rest-client'
         | 
| 5 5 | 
             
            require 'idealpostcodes/version'
         | 
| 6 | 
            -
             | 
| 6 | 
            +
             | 
| 7 | 
            +
            # Require utility libraries
         | 
| 7 8 | 
             
            require 'idealpostcodes/util'
         | 
| 8 9 | 
             
            require 'idealpostcodes/errors'
         | 
| 9 10 |  | 
| 11 | 
            +
            # Require Resources
         | 
| 12 | 
            +
            require 'idealpostcodes/key'
         | 
| 13 | 
            +
            require 'idealpostcodes/address'
         | 
| 14 | 
            +
            require 'idealpostcodes/postcode'
         | 
| 15 | 
            +
             | 
| 10 16 | 
             
            module IdealPostcodes
         | 
| 11 17 | 
             
            	@base_url = 'https://api.ideal-postcodes.co.uk'
         | 
| 12 18 | 
             
            	@version = '1'
         | 
| 13 19 |  | 
| 14 20 | 
             
            	class << self
         | 
| 15 | 
            -
            		attr_accessor :api_key, :base_url, :version
         | 
| 21 | 
            +
            		attr_accessor :api_key, :base_url, :version, :secret
         | 
| 16 22 | 
             
            	end
         | 
| 17 23 |  | 
| 18 24 | 
             
            	def self.request(method, path, params = {})
         | 
| @@ -38,11 +44,26 @@ module IdealPostcodes | |
| 38 44 | 
             
            				handle_client_error(error)
         | 
| 39 45 | 
             
            			end
         | 
| 40 46 | 
             
            		rescue RestClient::Exception, Errno::ECONNREFUSED => error
         | 
| 41 | 
            -
            			handle_client_error( | 
| 47 | 
            +
            			handle_client_error(error)
         | 
| 42 48 | 
             
            		end
         | 
| 43 49 | 
             
            		parse response.body
         | 
| 44 50 | 
             
            	end
         | 
| 45 51 |  | 
| 52 | 
            +
            	def self.apply_secret(secret)
         | 
| 53 | 
            +
            		@secret = secret
         | 
| 54 | 
            +
            	end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            	def self.key_available
         | 
| 57 | 
            +
            		response = Key.lookup @api_key
         | 
| 58 | 
            +
            		response[:available]
         | 
| 59 | 
            +
            	end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            	def self.key_details
         | 
| 62 | 
            +
            		raise IdealPostcodes::AuthenticationError.new('No Secret Key provided. ' +
         | 
| 63 | 
            +
            				'Set your secret key with IdealPostcodes.apply_secret #your_key') if @secret.nil?
         | 
| 64 | 
            +
            		response = Key.lookup_details @api_key, @secret
         | 
| 65 | 
            +
            	end
         | 
| 66 | 
            +
             | 
| 46 67 | 
             
            	private
         | 
| 47 68 |  | 
| 48 69 | 
             
            	def self.resource_url(path='')
         | 
| @@ -55,8 +76,8 @@ module IdealPostcodes | |
| 55 76 |  | 
| 56 77 | 
             
            	def self.parse(response)
         | 
| 57 78 | 
             
            		begin
         | 
| 58 | 
            -
                  Util.keys_to_sym  | 
| 59 | 
            -
                rescue  | 
| 79 | 
            +
                  Util.keys_to_sym JSON.parse(response)
         | 
| 80 | 
            +
                rescue JSON::ParserError => e
         | 
| 60 81 | 
             
                  raise handle_client_error(e)
         | 
| 61 82 | 
             
                end
         | 
| 62 83 | 
             
            	end
         | 
| @@ -85,7 +106,7 @@ module IdealPostcodes | |
| 85 106 | 
             
            	end
         | 
| 86 107 |  | 
| 87 108 | 
             
            	def self.general_error(response_code, response_body)
         | 
| 88 | 
            -
            		IdealPostcodesError.new  | 
| 109 | 
            +
            		IdealPostcodesError.new 'Invalid response object', response_code, response_body
         | 
| 89 110 | 
             
            	end
         | 
| 90 111 |  | 
| 91 112 | 
             
            end
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            module IdealPostcodes
         | 
| 2 | 
            +
            	module Address
         | 
| 3 | 
            +
            		class SearchResult
         | 
| 4 | 
            +
            			attr_reader :page, :limit, :addresses
         | 
| 5 | 
            +
            			def initialize response
         | 
| 6 | 
            +
            				@page = response[:result][:page]
         | 
| 7 | 
            +
            				@limit = response[:result][:limit]
         | 
| 8 | 
            +
            				@addresses = response[:result][:hits]
         | 
| 9 | 
            +
            			end
         | 
| 10 | 
            +
            		end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            		def self.lookup udprn
         | 
| 13 | 
            +
            			begin
         | 
| 14 | 
            +
            				response = IdealPostcodes.request :get, "addresses/#{udprn}"
         | 
| 15 | 
            +
            				address = response[:result]
         | 
| 16 | 
            +
            			rescue IdealPostcodes::IdealPostcodesError => error
         | 
| 17 | 
            +
            				raise error unless error.response_code == 4044
         | 
| 18 | 
            +
            				address = nil
         | 
| 19 | 
            +
            			end
         | 
| 20 | 
            +
            			address
         | 
| 21 | 
            +
            		end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            		def self.search search_term, options = {}
         | 
| 24 | 
            +
            			query = { query: search_term }
         | 
| 25 | 
            +
            			query[:limit] = options[:limit] unless options[:limit].nil?
         | 
| 26 | 
            +
            			query[:page] = options[:page] unless options[:page].nil?
         | 
| 27 | 
            +
            			response = IdealPostcodes.request :get, "addresses", query
         | 
| 28 | 
            +
            			SearchResult.new response
         | 
| 29 | 
            +
            		end
         | 
| 30 | 
            +
            	end
         | 
| 31 | 
            +
            end
         | 
| @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            module IdealPostcodes
         | 
| 2 | 
            +
            	module Key
         | 
| 3 | 
            +
            		def self.lookup api_key
         | 
| 4 | 
            +
            			response = IdealPostcodes.request :get, "keys/#{api_key}"
         | 
| 5 | 
            +
            			response[:result]
         | 
| 6 | 
            +
            		end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            		def self.lookup_details api_key, secret
         | 
| 9 | 
            +
            			response = IdealPostcodes.request :get, "keys/#{api_key}", { user_token: secret }
         | 
| 10 | 
            +
            			response[:result]
         | 
| 11 | 
            +
            		end
         | 
| 12 | 
            +
            	end
         | 
| 13 | 
            +
            end
         | 
| @@ -1,35 +1,22 @@ | |
| 1 1 | 
             
            module IdealPostcodes
         | 
| 2 | 
            -
            	 | 
| 3 | 
            -
             | 
| 4 | 
            -
            		attr_reader :postcode_data, :postcode, :addresses
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            		def initialize(postcode = nil, postcode_data = nil)
         | 
| 7 | 
            -
            			@raw = postcode_data
         | 
| 8 | 
            -
            			@addresses = (postcode_data.nil? || postcode_data[:result].nil?) ? [] : postcode_data[:result]
         | 
| 9 | 
            -
            			@postcode = postcode
         | 
| 10 | 
            -
            		end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
            		def self.lookup(postcode)
         | 
| 2 | 
            +
            	module Postcode
         | 
| 3 | 
            +
            		def self.lookup postcode
         | 
| 13 4 | 
             
            			begin
         | 
| 14 5 | 
             
            				response = IdealPostcodes.request :get, "postcodes/#{postcode}"
         | 
| 6 | 
            +
            				addresses = response[:result]
         | 
| 15 7 | 
             
            			rescue IdealPostcodes::ResourceNotFoundError => error
         | 
| 16 8 | 
             
            				raise error unless error.response_code == 4040
         | 
| 17 | 
            -
            				 | 
| 9 | 
            +
            				addresses = []
         | 
| 18 10 | 
             
            			end
         | 
| 19 | 
            -
            			 | 
| 11 | 
            +
            			addresses
         | 
| 20 12 | 
             
            		end
         | 
| 21 13 |  | 
| 22 | 
            -
            		def  | 
| 23 | 
            -
            			 | 
| 14 | 
            +
            		def self.find_by_location geolocation
         | 
| 15 | 
            +
            			query = {lonlat: "#{geolocation[:longitude]},#{geolocation[:latitude]}"}
         | 
| 16 | 
            +
            			query[:limit] = geolocation[:limit] unless geolocation[:limit].nil?
         | 
| 17 | 
            +
            			query[:radius] = geolocation[:radius] unless geolocation[:radius].nil?
         | 
| 18 | 
            +
            			response = IdealPostcodes.request :get, 'postcodes', query
         | 
| 19 | 
            +
            			response[:result]
         | 
| 24 20 | 
             
            		end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
            		def addresses
         | 
| 27 | 
            -
            			@addresses
         | 
| 28 | 
            -
            		end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
            		def to_s
         | 
| 31 | 
            -
            			addresses.to_s
         | 
| 32 | 
            -
            		end
         | 
| 33 | 
            -
             | 
| 34 21 | 
             
            	end
         | 
| 35 22 | 
             
            end
         | 
    
        data/lib/idealpostcodes/util.rb
    CHANGED
    
    | @@ -4,9 +4,9 @@ module IdealPostcodes | |
| 4 4 | 
             
            		def self.merge_params(hash)
         | 
| 5 5 | 
             
            			result = []
         | 
| 6 6 | 
             
            			hash.each do |key, value|
         | 
| 7 | 
            -
            				result << "#{CGI.escape(key.to_s)}=#{CGI.escape(value)}"
         | 
| 7 | 
            +
            				result << "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"
         | 
| 8 8 | 
             
            			end
         | 
| 9 | 
            -
            			result.join( | 
| 9 | 
            +
            			result.join('&')
         | 
| 10 10 | 
             
            		end
         | 
| 11 11 |  | 
| 12 12 | 
             
            		def self.keys_to_sym(object)
         | 
| @@ -0,0 +1,68 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe IdealPostcodes::Address do
         | 
| 4 | 
            +
            	describe '.lookup' do
         | 
| 5 | 
            +
            		it 'returns an address for a valid UDPRN' do
         | 
| 6 | 
            +
            			address = IdealPostcodes::Address.lookup 0
         | 
| 7 | 
            +
            			expect(is_address(address)).to eq(true)
         | 
| 8 | 
            +
            		end
         | 
| 9 | 
            +
            		it 'returns nil for an invalid UDPRN' do
         | 
| 10 | 
            +
            			address = IdealPostcodes::Address.lookup -1
         | 
| 11 | 
            +
            			expect(address).to be_nil
         | 
| 12 | 
            +
            		end
         | 
| 13 | 
            +
            		it 'raises an exception if invalid key' do
         | 
| 14 | 
            +
            			IdealPostcodes.api_key = 'foo'
         | 
| 15 | 
            +
            			expect {
         | 
| 16 | 
            +
            				IdealPostcodes::Address.lookup 0
         | 
| 17 | 
            +
            			}.to raise_error(IdealPostcodes::AuthenticationError)
         | 
| 18 | 
            +
            		end
         | 
| 19 | 
            +
            		it 'raises an exception if no lookups remaining' do
         | 
| 20 | 
            +
            			expect {
         | 
| 21 | 
            +
            				IdealPostcodes::Address.lookup -2
         | 
| 22 | 
            +
            			}.to raise_error(IdealPostcodes::TokenExhaustedError)
         | 
| 23 | 
            +
            		end
         | 
| 24 | 
            +
            		it 'raises an exception if limit breached' do
         | 
| 25 | 
            +
            			expect {
         | 
| 26 | 
            +
            				IdealPostcodes::Address.lookup -3
         | 
| 27 | 
            +
            			}.to raise_error(IdealPostcodes::LimitReachedError)
         | 
| 28 | 
            +
            		end
         | 
| 29 | 
            +
            	end	
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            	describe '.search' do
         | 
| 32 | 
            +
            		it 'returns results in a SearchResult object' do
         | 
| 33 | 
            +
            			results = IdealPostcodes::Address.search "ID1 1QD"
         | 
| 34 | 
            +
            			expect(results).to be_a(IdealPostcodes::Address::SearchResult)
         | 
| 35 | 
            +
            			expect(results.addresses.length).to be > 0
         | 
| 36 | 
            +
            			results.addresses.each do |address|
         | 
| 37 | 
            +
            				expect(is_address(address)).to eq(true)
         | 
| 38 | 
            +
            			end
         | 
| 39 | 
            +
            		end
         | 
| 40 | 
            +
            		it 'is sensitive to limit' do
         | 
| 41 | 
            +
            			limit = 1
         | 
| 42 | 
            +
            			results = IdealPostcodes::Address.search "High Street", limit: limit
         | 
| 43 | 
            +
            			expect(results.addresses.length).to equal(limit)
         | 
| 44 | 
            +
            			expect(results.limit).to equal(limit)
         | 
| 45 | 
            +
            		end
         | 
| 46 | 
            +
            		it 'is sensitive to page' do
         | 
| 47 | 
            +
            			page = 1
         | 
| 48 | 
            +
            			results = IdealPostcodes::Address.search "High Street", page: page
         | 
| 49 | 
            +
            			expect(results.page).to equal(page)
         | 
| 50 | 
            +
            		end
         | 
| 51 | 
            +
            		it 'raises an exception if invalid key' do
         | 
| 52 | 
            +
            			IdealPostcodes.api_key = 'foo'
         | 
| 53 | 
            +
            			expect {
         | 
| 54 | 
            +
            				results = IdealPostcodes::Address.search "ID1 1QD"
         | 
| 55 | 
            +
            			}.to raise_error(IdealPostcodes::AuthenticationError)
         | 
| 56 | 
            +
            		end
         | 
| 57 | 
            +
            		it 'raises an exception if no lookups remaining' do
         | 
| 58 | 
            +
            			expect {
         | 
| 59 | 
            +
            				results = IdealPostcodes::Address.search "ID1 CLIP"
         | 
| 60 | 
            +
            			}.to raise_error(IdealPostcodes::TokenExhaustedError)
         | 
| 61 | 
            +
            		end
         | 
| 62 | 
            +
            		it 'raises an exception if limit breached' do
         | 
| 63 | 
            +
            			expect {
         | 
| 64 | 
            +
            				results = IdealPostcodes::Address.search "ID1 CHOP"
         | 
| 65 | 
            +
            			}.to raise_error(IdealPostcodes::LimitReachedError)
         | 
| 66 | 
            +
            		end
         | 
| 67 | 
            +
            	end
         | 
| 68 | 
            +
            end
         | 
| @@ -0,0 +1,56 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe IdealPostcodes do
         | 
| 4 | 
            +
            	describe '#request' do
         | 
| 5 | 
            +
            		it 'generates a HTTP request' do
         | 
| 6 | 
            +
            			response = IdealPostcodes.request :get, 'postcodes/ID1 1QD'
         | 
| 7 | 
            +
            			expect(response[:code]).to eq(2000)
         | 
| 8 | 
            +
            		end
         | 
| 9 | 
            +
            		it 'raises an error if no key is provided' do
         | 
| 10 | 
            +
            			IdealPostcodes.api_key = nil
         | 
| 11 | 
            +
            			expect do
         | 
| 12 | 
            +
            				response = IdealPostcodes.request :get, 'postcodes/ID1 1QD'
         | 
| 13 | 
            +
            			end.to raise_error(IdealPostcodes::AuthenticationError)
         | 
| 14 | 
            +
            		end
         | 
| 15 | 
            +
            		it 'raises authentication error if invalid key is provided' do
         | 
| 16 | 
            +
            			IdealPostcodes.api_key = 'foo'
         | 
| 17 | 
            +
            			expect do
         | 
| 18 | 
            +
            				response = IdealPostcodes.request :get, 'postcodes/ID1 1QD'
         | 
| 19 | 
            +
            			end.to raise_error(IdealPostcodes::AuthenticationError)
         | 
| 20 | 
            +
            		end
         | 
| 21 | 
            +
            		it 'raises token exhausted error if key balance is depleted' do
         | 
| 22 | 
            +
            			expect do
         | 
| 23 | 
            +
            				response = IdealPostcodes.request :get, 'postcodes/ID1 CLIP'
         | 
| 24 | 
            +
            			end.to raise_error(IdealPostcodes::TokenExhaustedError)
         | 
| 25 | 
            +
            		end
         | 
| 26 | 
            +
            		it 'raises limit reached error if a limit has been breached' do
         | 
| 27 | 
            +
            			expect do
         | 
| 28 | 
            +
            				response = IdealPostcodes.request :get, 'postcodes/ID1 CHOP'
         | 
| 29 | 
            +
            			end.to raise_error(IdealPostcodes::LimitReachedError)
         | 
| 30 | 
            +
            		end
         | 
| 31 | 
            +
            	end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            	describe '.key_available' do
         | 
| 34 | 
            +
            		it 'returns true if key is available' do
         | 
| 35 | 
            +
            			IdealPostcodes.api_key = "iddqd"
         | 
| 36 | 
            +
            			expect(IdealPostcodes.key_available).to equal(true)
         | 
| 37 | 
            +
            		end
         | 
| 38 | 
            +
            		it 'returns false if key is unavailable' do
         | 
| 39 | 
            +
            			IdealPostcodes.api_key = "idkfa"
         | 
| 40 | 
            +
            			expect(IdealPostcodes.key_available).to equal(false)
         | 
| 41 | 
            +
            		end
         | 
| 42 | 
            +
            	end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            	describe '.key_details' do
         | 
| 45 | 
            +
            		it 'raises an exception if no secret is provided' do
         | 
| 46 | 
            +
            			expect {
         | 
| 47 | 
            +
            				IdealPostcodes.key_details
         | 
| 48 | 
            +
            			}.to raise_error(IdealPostcodes::AuthenticationError)
         | 
| 49 | 
            +
            		end
         | 
| 50 | 
            +
            		it 'returns key information' do
         | 
| 51 | 
            +
            			IdealPostcodes.apply_secret(secret_key)
         | 
| 52 | 
            +
            			response = IdealPostcodes.key_details
         | 
| 53 | 
            +
            			expect(is_key(response)).to eq(true)
         | 
| 54 | 
            +
            		end
         | 
| 55 | 
            +
            	end
         | 
| 56 | 
            +
            end
         | 
    
        data/spec/keys_spec.rb
    ADDED
    
    | @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe IdealPostcodes::Key do
         | 
| 4 | 
            +
            	describe '.lookup' do
         | 
| 5 | 
            +
            		it 'returns the availability status of a key (true key)' do
         | 
| 6 | 
            +
            			result = IdealPostcodes::Key.lookup "iddqd"
         | 
| 7 | 
            +
            			expect(result[:available]).to eq(true)
         | 
| 8 | 
            +
            		end
         | 
| 9 | 
            +
            		it 'returns the availability status of a key (false key)' do
         | 
| 10 | 
            +
            			result = IdealPostcodes::Key.lookup "idkfa"
         | 
| 11 | 
            +
            			expect(result[:available]).to eq(false)
         | 
| 12 | 
            +
            		end
         | 
| 13 | 
            +
            	end	
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            	describe '.lookup_details' do
         | 
| 16 | 
            +
            		it 'returns key details' do
         | 
| 17 | 
            +
            			result = IdealPostcodes::Key.lookup_details "gandhi", secret_key
         | 
| 18 | 
            +
            			expect(result[:lookups_remaining]).to_not be_nil
         | 
| 19 | 
            +
            			expect(result[:daily_limit]).to_not be_nil
         | 
| 20 | 
            +
            			expect(result[:individual_limit]).to_not be_nil
         | 
| 21 | 
            +
            			expect(result[:allowed_urls]).to_not be_nil
         | 
| 22 | 
            +
            			expect(result[:notifications]).to_not be_nil
         | 
| 23 | 
            +
            		end
         | 
| 24 | 
            +
            	end
         | 
| 25 | 
            +
            end
         | 
| @@ -0,0 +1,66 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe IdealPostcodes::Postcode do
         | 
| 4 | 
            +
            	describe '.lookup' do
         | 
| 5 | 
            +
            		it 'returns a list of addresses for a postcode' do
         | 
| 6 | 
            +
            			addresses = IdealPostcodes::Postcode.lookup 'ID1 1QD'
         | 
| 7 | 
            +
            			expect(addresses.length).to be > 0
         | 
| 8 | 
            +
            			addresses.each do |address|
         | 
| 9 | 
            +
            				expect(is_address(address)).to eq(true)
         | 
| 10 | 
            +
            				expect(address[:postcode]).to eq('ID1 1QD')
         | 
| 11 | 
            +
            			end
         | 
| 12 | 
            +
            		end
         | 
| 13 | 
            +
            		it 'returns an empty array if postcode does not exist' do
         | 
| 14 | 
            +
            			addresses = IdealPostcodes::Postcode.lookup 'ID1 KFA'
         | 
| 15 | 
            +
            			expect(addresses.length).to eq(0)
         | 
| 16 | 
            +
            		end
         | 
| 17 | 
            +
            		it 'raises an exception if key has run out of balance' do
         | 
| 18 | 
            +
            			expect {
         | 
| 19 | 
            +
            				IdealPostcodes::Postcode.lookup 'ID1 CLIP'
         | 
| 20 | 
            +
            			}.to raise_error(IdealPostcodes::TokenExhaustedError)
         | 
| 21 | 
            +
            		end
         | 
| 22 | 
            +
            		it 'raises an exception if limit has been reached' do
         | 
| 23 | 
            +
            			expect {
         | 
| 24 | 
            +
            				IdealPostcodes::Postcode.lookup 'ID1 CHOP'
         | 
| 25 | 
            +
            			}.to raise_error(IdealPostcodes::LimitReachedError)
         | 
| 26 | 
            +
            		end
         | 
| 27 | 
            +
            		it 'raises an exception if invalid key' do
         | 
| 28 | 
            +
            			IdealPostcodes.api_key = 'foo'
         | 
| 29 | 
            +
            			expect {
         | 
| 30 | 
            +
            				IdealPostcodes::Postcode.lookup 'ID1 1QD'
         | 
| 31 | 
            +
            			}.to raise_error(IdealPostcodes::AuthenticationError)
         | 
| 32 | 
            +
            		end
         | 
| 33 | 
            +
            	end
         | 
| 34 | 
            +
            	describe '.find_by_location' do
         | 
| 35 | 
            +
            		it 'returns an array of postcodes and locations' do
         | 
| 36 | 
            +
            			lon = 0.6298
         | 
| 37 | 
            +
            			lat = 51.7923
         | 
| 38 | 
            +
            			postcodes = IdealPostcodes::Postcode.find_by_location longitude: lon, latitude: lat
         | 
| 39 | 
            +
            			expect(postcodes.length).to be > 0
         | 
| 40 | 
            +
            			postcodes.each do |postcode|
         | 
| 41 | 
            +
            				expect(is_postcode_location(postcode)).to eq(true)
         | 
| 42 | 
            +
            			end
         | 
| 43 | 
            +
            		end
         | 
| 44 | 
            +
            		it 'returns an empty array if no results are found' do
         | 
| 45 | 
            +
            			lon = 0
         | 
| 46 | 
            +
            			lat = 0
         | 
| 47 | 
            +
            			postcodes = IdealPostcodes::Postcode.find_by_location longitude: lon, latitude: lat
         | 
| 48 | 
            +
            			expect(postcodes).to be_a(Array)
         | 
| 49 | 
            +
            			expect(postcodes.length).to eq(0)
         | 
| 50 | 
            +
            		end
         | 
| 51 | 
            +
            		it 'is sensitive to limit parameter' do
         | 
| 52 | 
            +
            			lon = 0.6298
         | 
| 53 | 
            +
            			lat = 51.7923
         | 
| 54 | 
            +
            			limit = 1
         | 
| 55 | 
            +
            			postcodes = IdealPostcodes::Postcode.find_by_location longitude: lon, latitude: lat, limit: limit
         | 
| 56 | 
            +
            			expect(postcodes.length).to eq(limit)
         | 
| 57 | 
            +
            		end
         | 
| 58 | 
            +
            		it 'is sensitive to radius parament' do
         | 
| 59 | 
            +
            			lon = 0.6298
         | 
| 60 | 
            +
            			lat = 51.7923
         | 
| 61 | 
            +
            			small_radius = IdealPostcodes::Postcode.find_by_location longitude: lon, latitude: lat, radius: 10
         | 
| 62 | 
            +
            			large_radius = IdealPostcodes::Postcode.find_by_location longitude: lon, latitude: lat, radius: 100
         | 
| 63 | 
            +
            			expect(large_radius.length > small_radius.length).to eq(true)
         | 
| 64 | 
            +
            		end
         | 
| 65 | 
            +
            	end
         | 
| 66 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | @@ -0,0 +1,65 @@ | |
| 1 | 
            +
            # Enable VCR
         | 
| 2 | 
            +
            require 'vcr'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            VCR.configure do |c|
         | 
| 5 | 
            +
            	c.cassette_library_dir = 'spec/vcr_cassettes'
         | 
| 6 | 
            +
            	c.hook_into :webmock
         | 
| 7 | 
            +
            end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            # Configure Ideal Postcodes lib
         | 
| 10 | 
            +
            require 'ideal_postcodes'
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            RSpec.configure do |c|
         | 
| 13 | 
            +
            	c.before(:each) do
         | 
| 14 | 
            +
                IdealPostcodes.base_url = 'https://localhost:1337'
         | 
| 15 | 
            +
            		IdealPostcodes.api_key = "gandhi"
         | 
| 16 | 
            +
            		IdealPostcodes.apply_secret nil
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            	c.around(:each) do |example|
         | 
| 20 | 
            +
            		VCR.use_cassette(example.metadata[:full_description]) do
         | 
| 21 | 
            +
            			example.run
         | 
| 22 | 
            +
            		end
         | 
| 23 | 
            +
            	end
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            def contains_attributes attribute_list, target
         | 
| 27 | 
            +
            	result = true
         | 
| 28 | 
            +
            	attribute_list.each do |attribute|
         | 
| 29 | 
            +
            		result = false if target[attribute].nil?
         | 
| 30 | 
            +
            	end
         | 
| 31 | 
            +
            	result
         | 
| 32 | 
            +
            end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            def postcode_location_elements
         | 
| 35 | 
            +
            	[:postcode, :longitude, :latitude, :northings, :eastings]
         | 
| 36 | 
            +
            end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            def is_postcode_location(postcode)
         | 
| 39 | 
            +
            	contains_attributes postcode_location_elements, postcode
         | 
| 40 | 
            +
            end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            def address_elements
         | 
| 43 | 
            +
            	[:postcode, :postcode_inward, :postcode_outward, :post_town, :dependant_locality, 
         | 
| 44 | 
            +
            		:double_dependant_locality, :thoroughfare, :dependant_thoroughfare, 
         | 
| 45 | 
            +
            		:building_number, :building_name, :sub_building_name, :po_box, :department_name, 
         | 
| 46 | 
            +
            		:organisation_name, :udprn, :postcode_type, :su_organisation_indicator, 
         | 
| 47 | 
            +
            		:delivery_point_suffix, :line_1, :line_2, :line_3, :premise, :county, 
         | 
| 48 | 
            +
            		:district, :ward, :longitude, :latitude, :eastings, :northings]
         | 
| 49 | 
            +
            end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            def is_address(address)
         | 
| 52 | 
            +
            	contains_attributes address_elements, address
         | 
| 53 | 
            +
            end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            def key_elements
         | 
| 56 | 
            +
            	[:lookups_remaining, :daily_limit, :individual_limit, :allowed_urls, :notifications]
         | 
| 57 | 
            +
            end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            def is_key(key)
         | 
| 60 | 
            +
            	contains_attributes key_elements, key
         | 
| 61 | 
            +
            end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
            def secret_key
         | 
| 64 | 
            +
            	"uk_hxp6ouk0rmyXoobVJnehrsQcdvTfb"
         | 
| 65 | 
            +
            end
         |