auspost 0.8.5
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.
- data/.bnsignore +18 -0
 - data/History.txt +4 -0
 - data/README.txt +73 -0
 - data/Rakefile +22 -0
 - data/bin/auspost +7 -0
 - data/lib/auspost.rb +48 -0
 - data/lib/auspost/active_record.rb +5 -0
 - data/lib/auspost/active_record/validations.rb +82 -0
 - data/lib/auspost/postie.rb +172 -0
 - data/spec/auspost/active_record/validations_spec.rb +72 -0
 - data/spec/auspost/postie_spec.rb +55 -0
 - data/spec/fixtures/auspost.html +187 -0
 - data/spec/fixtures/postal_worker.rb +39 -0
 - data/spec/spec_helper.rb +15 -0
 - metadata +83 -0
 
    
        data/.bnsignore
    ADDED
    
    | 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # The list of files that should be ignored by Mr Bones.
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Lines that start with '#' are comments.
         
     | 
| 
      
 3 
     | 
    
         
            +
            #
         
     | 
| 
      
 4 
     | 
    
         
            +
            # A .gitignore file can be used instead by setting it as the ignore
         
     | 
| 
      
 5 
     | 
    
         
            +
            # file in your Rakefile:
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            #   Bones {
         
     | 
| 
      
 8 
     | 
    
         
            +
            #     ignore_file  '.gitignore'
         
     | 
| 
      
 9 
     | 
    
         
            +
            #   }
         
     | 
| 
      
 10 
     | 
    
         
            +
            #
         
     | 
| 
      
 11 
     | 
    
         
            +
            # For a project with a C extension, the following would be a good set of
         
     | 
| 
      
 12 
     | 
    
         
            +
            # exclude patterns (uncomment them if you want to use them):
         
     | 
| 
      
 13 
     | 
    
         
            +
            # *.[oa]
         
     | 
| 
      
 14 
     | 
    
         
            +
            # *~
         
     | 
| 
      
 15 
     | 
    
         
            +
            announcement.txt
         
     | 
| 
      
 16 
     | 
    
         
            +
            coverage
         
     | 
| 
      
 17 
     | 
    
         
            +
            doc
         
     | 
| 
      
 18 
     | 
    
         
            +
            pkg
         
     | 
    
        data/History.txt
    ADDED
    
    
    
        data/README.txt
    ADDED
    
    | 
         @@ -0,0 +1,73 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            auspost
         
     | 
| 
      
 2 
     | 
    
         
            +
                by Cameron Barrie
         
     | 
| 
      
 3 
     | 
    
         
            +
                http://wiki.github.com/whalec/auspost
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            == DESCRIPTION:
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            Give you the ability to search the Australia Post Web site with either Suburb or Postcode, and return an array of Locations.
         
     | 
| 
      
 8 
     | 
    
         
            +
            Also add's validation methods to ActiveRecord Objects to allow you to validate that A Postcode + State + Suburb is correct
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            == FEATURES/PROBLEMS:
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            ActiveRecord Validations - validates_location
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            == SYNOPSIS:
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              class Foo < ActiveRecord::Base
         
     | 
| 
      
 18 
     | 
    
         
            +
                include Auspost::Postie
         
     | 
| 
      
 19 
     | 
    
         
            +
                
         
     | 
| 
      
 20 
     | 
    
         
            +
                before_save :check_address
         
     | 
| 
      
 21 
     | 
    
         
            +
                
         
     | 
| 
      
 22 
     | 
    
         
            +
                def check_address
         
     | 
| 
      
 23 
     | 
    
         
            +
                  location?(:postcode => 2038, :suburb => "Annandale", :state => "NSW")
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
              
         
     | 
| 
      
 27 
     | 
    
         
            +
              or 
         
     | 
| 
      
 28 
     | 
    
         
            +
              
         
     | 
| 
      
 29 
     | 
    
         
            +
              require 'auspost/active_record'
         
     | 
| 
      
 30 
     | 
    
         
            +
              class Foo < ActiveRecord::Base
         
     | 
| 
      
 31 
     | 
    
         
            +
              
         
     | 
| 
      
 32 
     | 
    
         
            +
                validate_location
         
     | 
| 
      
 33 
     | 
    
         
            +
              
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            == REQUIREMENTS:
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            Nokogiri - For teh XML parsing.
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            == INSTALL:
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            sudo gem install auspost
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            == TODO:
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            Validations for Active Record should take more options, including mapping the suburb, postcode and state to other columns
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            validate_location :suburb => :home, :state => "state.name", :on => [:create, :change], :if => lambda { !home.blank? && !postcode.blank? }
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            == LICENSE:
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            (The MIT License)
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            Copyright (c) 2009
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 57 
     | 
    
         
            +
            a copy of this software and associated documentation files (the
         
     | 
| 
      
 58 
     | 
    
         
            +
            'Software'), to deal in the Software without restriction, including
         
     | 
| 
      
 59 
     | 
    
         
            +
            without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 60 
     | 
    
         
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 61 
     | 
    
         
            +
            permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 62 
     | 
    
         
            +
            the following conditions:
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be
         
     | 
| 
      
 65 
     | 
    
         
            +
            included in all copies or substantial portions of the Software.
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 68 
     | 
    
         
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 69 
     | 
    
         
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
         
     | 
| 
      
 70 
     | 
    
         
            +
            IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
         
     | 
| 
      
 71 
     | 
    
         
            +
            CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
         
     | 
| 
      
 72 
     | 
    
         
            +
            TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
         
     | 
| 
      
 73 
     | 
    
         
            +
            SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            begin
         
     | 
| 
      
 2 
     | 
    
         
            +
              require 'bones'
         
     | 
| 
      
 3 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 4 
     | 
    
         
            +
              abort '### Please install the "bones" gem ###'
         
     | 
| 
      
 5 
     | 
    
         
            +
            end
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            ensure_in_path 'lib'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'auspost'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            task :default => 'test:run'
         
     | 
| 
      
 11 
     | 
    
         
            +
            task 'gem:release' => 'test:run'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            Bones {
         
     | 
| 
      
 14 
     | 
    
         
            +
              name     'auspost'
         
     | 
| 
      
 15 
     | 
    
         
            +
              authors  'Cameron Barrie'
         
     | 
| 
      
 16 
     | 
    
         
            +
              email    'camwritescode@gmail.com'
         
     | 
| 
      
 17 
     | 
    
         
            +
              dependencies ['nokogiri', "memcache-client"]
         
     | 
| 
      
 18 
     | 
    
         
            +
              url      'http://www.camwritescode.com/auspost'
         
     | 
| 
      
 19 
     | 
    
         
            +
              version  Auspost::VERSION
         
     | 
| 
      
 20 
     | 
    
         
            +
            }
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            # EOF
         
     | 
    
        data/bin/auspost
    ADDED
    
    
    
        data/lib/auspost.rb
    ADDED
    
    | 
         @@ -0,0 +1,48 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Auspost
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              # :stopdoc:
         
     | 
| 
      
 4 
     | 
    
         
            +
              VERSION = '0.8.5'
         
     | 
| 
      
 5 
     | 
    
         
            +
              LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
         
     | 
| 
      
 6 
     | 
    
         
            +
              PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
         
     | 
| 
      
 7 
     | 
    
         
            +
              # :startdoc:
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              # Returns the version string for the library.
         
     | 
| 
      
 10 
     | 
    
         
            +
              #
         
     | 
| 
      
 11 
     | 
    
         
            +
              def self.version
         
     | 
| 
      
 12 
     | 
    
         
            +
                VERSION
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              # Returns the library path for the module. If any arguments are given,
         
     | 
| 
      
 16 
     | 
    
         
            +
              # they will be joined to the end of the libray path using
         
     | 
| 
      
 17 
     | 
    
         
            +
              # <tt>File.join</tt>.
         
     | 
| 
      
 18 
     | 
    
         
            +
              #
         
     | 
| 
      
 19 
     | 
    
         
            +
              def self.libpath( *args )
         
     | 
| 
      
 20 
     | 
    
         
            +
                args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              # Returns the lpath for the module. If any arguments are given,
         
     | 
| 
      
 24 
     | 
    
         
            +
              # they will be joined to the end of the path using
         
     | 
| 
      
 25 
     | 
    
         
            +
              # <tt>File.join</tt>.
         
     | 
| 
      
 26 
     | 
    
         
            +
              #
         
     | 
| 
      
 27 
     | 
    
         
            +
              def self.path( *args )
         
     | 
| 
      
 28 
     | 
    
         
            +
                args.empty? ? PATH : ::File.join(PATH, args.flatten)
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              # Utility method used to require all files ending in .rb that lie in the
         
     | 
| 
      
 32 
     | 
    
         
            +
              # directory below this file that has the same name as the filename passed
         
     | 
| 
      
 33 
     | 
    
         
            +
              # in. Optionally, a specific _directory_ name can be passed in such that
         
     | 
| 
      
 34 
     | 
    
         
            +
              # the _filename_ does not have to be equivalent to the directory.
         
     | 
| 
      
 35 
     | 
    
         
            +
              #
         
     | 
| 
      
 36 
     | 
    
         
            +
              def self.require_all_libs_relative_to( fname, dir = nil )
         
     | 
| 
      
 37 
     | 
    
         
            +
                dir ||= ::File.basename(fname, '.*')
         
     | 
| 
      
 38 
     | 
    
         
            +
                search_me = ::File.expand_path(
         
     | 
| 
      
 39 
     | 
    
         
            +
                    ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                Dir.glob(search_me).sort.each {|rb| require rb}
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            end  # module Auspost
         
     | 
| 
      
 45 
     | 
    
         
            +
            require 'open-uri'
         
     | 
| 
      
 46 
     | 
    
         
            +
            require 'nokogiri'
         
     | 
| 
      
 47 
     | 
    
         
            +
            require 'memcache'
         
     | 
| 
      
 48 
     | 
    
         
            +
            require 'auspost/postie'
         
     | 
| 
         @@ -0,0 +1,82 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Auspost
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Postie
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                module ActiveRecord
         
     | 
| 
      
 5 
     | 
    
         
            +
                  module Validations
         
     | 
| 
      
 6 
     | 
    
         
            +
                    
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @@valid_attributes = {
         
     | 
| 
      
 8 
     | 
    
         
            +
                      :state    => {:accessor => :state, :message => ["%s is not found in the %s postcode", :state, :postcode] },
         
     | 
| 
      
 9 
     | 
    
         
            +
                      :postcode => {:accessor => :postcode, :message => ["%s cannot be found", :postcode] },
         
     | 
| 
      
 10 
     | 
    
         
            +
                      :suburb   => {:accessor => :suburb, :message => ["%s is not found in the %s postcode", :suburb, :postcode] },
         
     | 
| 
      
 11 
     | 
    
         
            +
                    }
         
     | 
| 
      
 12 
     | 
    
         
            +
                    
         
     | 
| 
      
 13 
     | 
    
         
            +
                    def self.included(base)
         
     | 
| 
      
 14 
     | 
    
         
            +
                      base.extend ClassMethods
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                    
         
     | 
| 
      
 17 
     | 
    
         
            +
                    
         
     | 
| 
      
 18 
     | 
    
         
            +
                    def validate_location
         
     | 
| 
      
 19 
     | 
    
         
            +
                      result = location?(map_attributes)
         
     | 
| 
      
 20 
     | 
    
         
            +
                      if result && !result.status
         
     | 
| 
      
 21 
     | 
    
         
            +
                        result.errors.each do |error|
         
     | 
| 
      
 22 
     | 
    
         
            +
                          message = @@valid_attributes[error.accessor][:message]
         
     | 
| 
      
 23 
     | 
    
         
            +
                          if message.is_a?(String)
         
     | 
| 
      
 24 
     | 
    
         
            +
                            errors.add(error.accessor, message)
         
     | 
| 
      
 25 
     | 
    
         
            +
                          else
         
     | 
| 
      
 26 
     | 
    
         
            +
                            mappings = message[1..-1].map do |x|
         
     | 
| 
      
 27 
     | 
    
         
            +
                              if x.to_s.include?(".")
         
     | 
| 
      
 28 
     | 
    
         
            +
                                methods = x.split(".")
         
     | 
| 
      
 29 
     | 
    
         
            +
                                send(methods.first).send(methods.last).to_s.upcase
         
     | 
| 
      
 30 
     | 
    
         
            +
                              else
         
     | 
| 
      
 31 
     | 
    
         
            +
                                send(x).to_s.upcase
         
     | 
| 
      
 32 
     | 
    
         
            +
                              end
         
     | 
| 
      
 33 
     | 
    
         
            +
                            end
         
     | 
| 
      
 34 
     | 
    
         
            +
                            errors.add(error.accessor, message.first % mappings)
         
     | 
| 
      
 35 
     | 
    
         
            +
                          end
         
     | 
| 
      
 36 
     | 
    
         
            +
                        end
         
     | 
| 
      
 37 
     | 
    
         
            +
                      end
         
     | 
| 
      
 38 
     | 
    
         
            +
                    end
         
     | 
| 
      
 39 
     | 
    
         
            +
                    
         
     | 
| 
      
 40 
     | 
    
         
            +
                    def valid_attributes
         
     | 
| 
      
 41 
     | 
    
         
            +
                      @@valid_attributes
         
     | 
| 
      
 42 
     | 
    
         
            +
                    end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                    protected
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                    def map_attributes
         
     | 
| 
      
 47 
     | 
    
         
            +
                      { 
         
     | 
| 
      
 48 
     | 
    
         
            +
                        :state    => get_column(:state),
         
     | 
| 
      
 49 
     | 
    
         
            +
                        :postcode => get_column(:postcode),
         
     | 
| 
      
 50 
     | 
    
         
            +
                        :suburb   => get_column(:suburb)
         
     | 
| 
      
 51 
     | 
    
         
            +
                      }
         
     | 
| 
      
 52 
     | 
    
         
            +
                    end
         
     | 
| 
      
 53 
     | 
    
         
            +
                    
         
     | 
| 
      
 54 
     | 
    
         
            +
                    def get_column(column)
         
     | 
| 
      
 55 
     | 
    
         
            +
                      if @@valid_attributes[column][:accessor].nil?
         
     | 
| 
      
 56 
     | 
    
         
            +
                        column
         
     | 
| 
      
 57 
     | 
    
         
            +
                      elsif @@valid_attributes[column][:accessor].is_a?(String) && @@valid_attributes[column][:accessor].include?(".")
         
     | 
| 
      
 58 
     | 
    
         
            +
                        association = @@valid_attributes[column][:accessor].split(".")
         
     | 
| 
      
 59 
     | 
    
         
            +
                        self.send(association.first.to_sym).send(association.last.to_sym)
         
     | 
| 
      
 60 
     | 
    
         
            +
                      else
         
     | 
| 
      
 61 
     | 
    
         
            +
                        self.send(@@valid_attributes[column][:accessor]) || column
         
     | 
| 
      
 62 
     | 
    
         
            +
                      end
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                    module ClassMethods
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                      include Validations
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                      # I'll add some validations here...
         
     | 
| 
      
 71 
     | 
    
         
            +
                      def validate_location(*args)
         
     | 
| 
      
 72 
     | 
    
         
            +
                        valid_attributes.update(args.extract_options!)
         
     | 
| 
      
 73 
     | 
    
         
            +
                        validate :validate_location, valid_attributes
         
     | 
| 
      
 74 
     | 
    
         
            +
                      end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
                end #ActiveRecord
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,172 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'cgi'
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Auspost
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              module Postie
         
     | 
| 
      
 5 
     | 
    
         
            +
                
         
     | 
| 
      
 6 
     | 
    
         
            +
                class Cache
         
     | 
| 
      
 7 
     | 
    
         
            +
                  
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Over ride these two class variables to change your memcache settings
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @@memcache_host = "localhost"
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @@memcache_port = "11211"
         
     | 
| 
      
 11 
     | 
    
         
            +
                  
         
     | 
| 
      
 12 
     | 
    
         
            +
                  def initialize
         
     | 
| 
      
 13 
     | 
    
         
            +
                    if Object.const_defined? :Rails
         
     | 
| 
      
 14 
     | 
    
         
            +
                      Rails.cache
         
     | 
| 
      
 15 
     | 
    
         
            +
                    else
         
     | 
| 
      
 16 
     | 
    
         
            +
                      @cache = MemCache.new "#{@@memcache_host}:#{@@memcache_port}", :namespace => 'auspost'
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  
         
     | 
| 
      
 20 
     | 
    
         
            +
                  def write(key, object)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    if @cache
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @cache.add(key, object) if @cache.servers.map{|s| s.alive?}.include?(true)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    else
         
     | 
| 
      
 24 
     | 
    
         
            +
                      Rails.cache.write(key, object)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
                  
         
     | 
| 
      
 28 
     | 
    
         
            +
                  def read(key)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    if @cache
         
     | 
| 
      
 30 
     | 
    
         
            +
                      @cache.get(key) if @cache.servers.map{|s| s.alive?}.include?(true)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    else
         
     | 
| 
      
 32 
     | 
    
         
            +
                      Rails.cache.read(key)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
                
         
     | 
| 
      
 37 
     | 
    
         
            +
                class Suburb
         
     | 
| 
      
 38 
     | 
    
         
            +
                  def initialize(attrs)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    @suburb   = attrs[:suburb].downcase
         
     | 
| 
      
 40 
     | 
    
         
            +
                    @postcode = attrs[:postcode].to_i
         
     | 
| 
      
 41 
     | 
    
         
            +
                    @state    = attrs[:state].downcase
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
                  
         
     | 
| 
      
 44 
     | 
    
         
            +
                  def suburb?(attrs)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    attrs[:suburb].downcase == @suburb
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
                  
         
     | 
| 
      
 48 
     | 
    
         
            +
                  def state?(attrs)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    attrs[:state].downcase == @state.downcase
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
                  
         
     | 
| 
      
 52 
     | 
    
         
            +
                  def postcode?(attrs)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    attrs[:postcode].to_i == @postcode
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
                  
         
     | 
| 
      
 56 
     | 
    
         
            +
                  def eql?(attrs)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    suburb?(attrs) && postcode?(attrs) && state?(attrs)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
                  
         
     | 
| 
      
 60 
     | 
    
         
            +
                  def to_i(attrs)
         
     | 
| 
      
 61 
     | 
    
         
            +
                    (suburb?(attrs) ? 1 : 0) + 
         
     | 
| 
      
 62 
     | 
    
         
            +
                      (state?(attrs) ? 1 : 0) +
         
     | 
| 
      
 63 
     | 
    
         
            +
                        (postcode?(attrs) ? 1 : 0)
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
                
         
     | 
| 
      
 67 
     | 
    
         
            +
                class Result
         
     | 
| 
      
 68 
     | 
    
         
            +
                  
         
     | 
| 
      
 69 
     | 
    
         
            +
                  attr_reader :status, :errors
         
     | 
| 
      
 70 
     | 
    
         
            +
                  
         
     | 
| 
      
 71 
     | 
    
         
            +
                  def initialize(status)
         
     | 
| 
      
 72 
     | 
    
         
            +
                    @status = status
         
     | 
| 
      
 73 
     | 
    
         
            +
                    @errors = [] if !@status
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
                  
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
                
         
     | 
| 
      
 78 
     | 
    
         
            +
                class Error
         
     | 
| 
      
 79 
     | 
    
         
            +
                  
         
     | 
| 
      
 80 
     | 
    
         
            +
                  attr_reader :accessor
         
     | 
| 
      
 81 
     | 
    
         
            +
                  
         
     | 
| 
      
 82 
     | 
    
         
            +
                  def initialize(accessor)
         
     | 
| 
      
 83 
     | 
    
         
            +
                    @accessor = accessor
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
                  
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                # This is the method that returns whether a location is correct or not.
         
     | 
| 
      
 90 
     | 
    
         
            +
                # It requires three attributes
         
     | 
| 
      
 91 
     | 
    
         
            +
                # :postcode, :suburb & :state such as
         
     | 
| 
      
 92 
     | 
    
         
            +
                # location?(:postcode => 2038, :suburb => "Annandale", :state => "NSW") #=> Result#status => true
         
     | 
| 
      
 93 
     | 
    
         
            +
                # location?(:postcode => 2010, :suburb => "Annandale", :state => "NSW") #=> Result#status => false 
         
     | 
| 
      
 94 
     | 
    
         
            +
                # Result#errors => Error#accessor => :suburb && Error#message => "Annandale does not match 2010 postcode"
         
     | 
| 
      
 95 
     | 
    
         
            +
                # The results of a request to a given postcode is cached in memcached if available or in
         
     | 
| 
      
 96 
     | 
    
         
            +
                # your Rails.cache store if you're in a Rails project.
         
     | 
| 
      
 97 
     | 
    
         
            +
                def location?(attrs = {})
         
     | 
| 
      
 98 
     | 
    
         
            +
                  map_attributes!(attrs)
         
     | 
| 
      
 99 
     | 
    
         
            +
                  url       = "http://www1.auspost.com.au/postcodes/index.asp?Locality=&sub=1&State=&Postcode=#{CGI::escape(@postcode)}&submit1=Search"
         
     | 
| 
      
 100 
     | 
    
         
            +
                  @content  = get(url)
         
     | 
| 
      
 101 
     | 
    
         
            +
                  check_results(attrs)
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
                
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                protected
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                def cache
         
     | 
| 
      
 108 
     | 
    
         
            +
                  @cache ||= set_cache 
         
     | 
| 
      
 109 
     | 
    
         
            +
                end
         
     | 
| 
      
 110 
     | 
    
         
            +
                
         
     | 
| 
      
 111 
     | 
    
         
            +
                def set_cache
         
     | 
| 
      
 112 
     | 
    
         
            +
                  @cache = Cache.new
         
     | 
| 
      
 113 
     | 
    
         
            +
                end
         
     | 
| 
      
 114 
     | 
    
         
            +
                
         
     | 
| 
      
 115 
     | 
    
         
            +
                def get(url)
         
     | 
| 
      
 116 
     | 
    
         
            +
                  @results = check_cache || get_and_cache(url)
         
     | 
| 
      
 117 
     | 
    
         
            +
                end
         
     | 
| 
      
 118 
     | 
    
         
            +
                
         
     | 
| 
      
 119 
     | 
    
         
            +
                def check_cache
         
     | 
| 
      
 120 
     | 
    
         
            +
                  cache.read(@postcode)
         
     | 
| 
      
 121 
     | 
    
         
            +
                end
         
     | 
| 
      
 122 
     | 
    
         
            +
                
         
     | 
| 
      
 123 
     | 
    
         
            +
                def get_and_cache(url)
         
     | 
| 
      
 124 
     | 
    
         
            +
                  object    = open(url)
         
     | 
| 
      
 125 
     | 
    
         
            +
                  @table    = Nokogiri::HTML(object).xpath('//table[3]/tr/td[2]/table/tr/td/font/table/tr[2]/td/table/tr')
         
     | 
| 
      
 126 
     | 
    
         
            +
                  content   = map_results
         
     | 
| 
      
 127 
     | 
    
         
            +
                  content.delete_if{|x| x.nil?}
         
     | 
| 
      
 128 
     | 
    
         
            +
                  cache.write(@postcode, content)
         
     | 
| 
      
 129 
     | 
    
         
            +
                  content
         
     | 
| 
      
 130 
     | 
    
         
            +
                end
         
     | 
| 
      
 131 
     | 
    
         
            +
                
         
     | 
| 
      
 132 
     | 
    
         
            +
                def map_attributes!(attrs)
         
     | 
| 
      
 133 
     | 
    
         
            +
                  raise ArgumentError, "You must supply a suburb" if attrs[:suburb].nil?
         
     | 
| 
      
 134 
     | 
    
         
            +
                  raise ArgumentError, "You must supply a state" if attrs[:state].nil?
         
     | 
| 
      
 135 
     | 
    
         
            +
                  raise ArgumentError, "You must supply a postcode" if attrs[:postcode].nil?
         
     | 
| 
      
 136 
     | 
    
         
            +
                  attrs.values.map!{|value| value.to_s.downcase! }
         
     | 
| 
      
 137 
     | 
    
         
            +
                  @postcode = attrs[:postcode].to_s
         
     | 
| 
      
 138 
     | 
    
         
            +
                end
         
     | 
| 
      
 139 
     | 
    
         
            +
                
         
     | 
| 
      
 140 
     | 
    
         
            +
                def map_results
         
     | 
| 
      
 141 
     | 
    
         
            +
                  @table.map do |row|
         
     | 
| 
      
 142 
     | 
    
         
            +
                    content = row.content.strip if row.content.include?("LOCATION:")
         
     | 
| 
      
 143 
     | 
    
         
            +
                    if content
         
     | 
| 
      
 144 
     | 
    
         
            +
                      s = content.index("LOCATION: ")
         
     | 
| 
      
 145 
     | 
    
         
            +
                      e = content.index(",")
         
     | 
| 
      
 146 
     | 
    
         
            +
                      suburb = content[s..e-1].split(" ").last
         
     | 
| 
      
 147 
     | 
    
         
            +
                      state  = content[e+2..e+4]
         
     | 
| 
      
 148 
     | 
    
         
            +
                      final = Suburb.new(:suburb => suburb, :state => state, :postcode => @postcode)
         
     | 
| 
      
 149 
     | 
    
         
            +
                    end
         
     | 
| 
      
 150 
     | 
    
         
            +
                  end
         
     | 
| 
      
 151 
     | 
    
         
            +
                end
         
     | 
| 
      
 152 
     | 
    
         
            +
                
         
     | 
| 
      
 153 
     | 
    
         
            +
                def check_results(attrs)
         
     | 
| 
      
 154 
     | 
    
         
            +
                  if @results.map{|suburb| suburb.eql?(attrs)}.include?(true)
         
     | 
| 
      
 155 
     | 
    
         
            +
                    Result.new(true)
         
     | 
| 
      
 156 
     | 
    
         
            +
                  else
         
     | 
| 
      
 157 
     | 
    
         
            +
                    generate_result_with_errors(attrs)
         
     | 
| 
      
 158 
     | 
    
         
            +
                  end
         
     | 
| 
      
 159 
     | 
    
         
            +
                end
         
     | 
| 
      
 160 
     | 
    
         
            +
                
         
     | 
| 
      
 161 
     | 
    
         
            +
                def generate_result_with_errors(attrs)
         
     | 
| 
      
 162 
     | 
    
         
            +
                  result = Result.new(false)
         
     | 
| 
      
 163 
     | 
    
         
            +
                  error_count = @results.map{|r| r.to_i(attrs) }
         
     | 
| 
      
 164 
     | 
    
         
            +
                  main_error = @results[error_count.index(error_count.sort.last)]
         
     | 
| 
      
 165 
     | 
    
         
            +
                  result.errors << Error.new(:suburb) if !main_error.suburb?(attrs)
         
     | 
| 
      
 166 
     | 
    
         
            +
                  result.errors << Error.new(:state) if !main_error.state?(attrs)
         
     | 
| 
      
 167 
     | 
    
         
            +
                  result
         
     | 
| 
      
 168 
     | 
    
         
            +
                end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
              end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,72 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.join(File.dirname(__FILE__), "../../spec_helper")
         
     | 
| 
      
 2 
     | 
    
         
            +
            require File.join(File.dirname(__FILE__), "../../fixtures/postal_worker")
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            describe PostalWorker, "without auspost/active_record required" do
         
     | 
| 
      
 5 
     | 
    
         
            +
              
         
     | 
| 
      
 6 
     | 
    
         
            +
              it "should not respond to a method validate_location" do
         
     | 
| 
      
 7 
     | 
    
         
            +
                PostalWorker.should_not respond_to(:validate_location)
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
              
         
     | 
| 
      
 10 
     | 
    
         
            +
            end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            describe PostalWorker, "with auspost/active_record required" do
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              # require needs to be in the before block, otherwise it's called when the file is required or the describe blocks are called.
         
     | 
| 
      
 16 
     | 
    
         
            +
              # causing failure to the above spec
         
     | 
| 
      
 17 
     | 
    
         
            +
              before(:all) do
         
     | 
| 
      
 18 
     | 
    
         
            +
                require 'auspost/active_record'
         
     | 
| 
      
 19 
     | 
    
         
            +
                PostalWorker.validate_location
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              before do
         
     | 
| 
      
 23 
     | 
    
         
            +
                @valid_attributes = {:address => "William St", :suburb => "Annandale", :postcode => "2038", :state => "NSW"}
         
     | 
| 
      
 24 
     | 
    
         
            +
                @invalid_attributes = {:address => "William St", :suburb => "Annandale", :postcode => "2000", :state => "VIC"}
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
              
         
     | 
| 
      
 27 
     | 
    
         
            +
              it "should have a method validate_location" do
         
     | 
| 
      
 28 
     | 
    
         
            +
                PostalWorker.should respond_to(:validate_location)
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
              
         
     | 
| 
      
 31 
     | 
    
         
            +
              it "should not be valid" do
         
     | 
| 
      
 32 
     | 
    
         
            +
                @worker = PostalWorker.new(@invalid_attributes)
         
     | 
| 
      
 33 
     | 
    
         
            +
                @worker.should_not be_valid
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
              
         
     | 
| 
      
 36 
     | 
    
         
            +
              it "should validate an address" do
         
     | 
| 
      
 37 
     | 
    
         
            +
                @worker = PostalWorker.new({:suburb => "Rozelle", :postcode => "2039", :state => "NSW"})
         
     | 
| 
      
 38 
     | 
    
         
            +
                @worker.should be_valid
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
              
         
     | 
| 
      
 41 
     | 
    
         
            +
              it "should return a useful error message on the state" do
         
     | 
| 
      
 42 
     | 
    
         
            +
                @worker = PostalWorker.new(@invalid_attributes)
         
     | 
| 
      
 43 
     | 
    
         
            +
                @worker.should_not be_valid
         
     | 
| 
      
 44 
     | 
    
         
            +
                @worker.errors.on(:state).should eql("VIC is not found in the 2000 postcode")
         
     | 
| 
      
 45 
     | 
    
         
            +
                @worker.errors.on(:suburb).should eql("ANNANDALE is not found in the 2000 postcode")
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
              
         
     | 
| 
      
 48 
     | 
    
         
            +
              it "should return a useful error message on the suburb" do
         
     | 
| 
      
 49 
     | 
    
         
            +
                @worker = PostalWorker.new(@valid_attributes.merge(:suburb => "Rozelle"))
         
     | 
| 
      
 50 
     | 
    
         
            +
                @worker.should_not be_valid
         
     | 
| 
      
 51 
     | 
    
         
            +
                @worker.errors.on(:suburb).should eql("ROZELLE is not found in the 2038 postcode")
         
     | 
| 
      
 52 
     | 
    
         
            +
                @worker.errors.on(:state).should be_nil
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
            end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            describe MashedPostalWorker, "with options set on the validation" do
         
     | 
| 
      
 58 
     | 
    
         
            +
              before(:all) do
         
     | 
| 
      
 59 
     | 
    
         
            +
                require 'auspost/active_record'
         
     | 
| 
      
 60 
     | 
    
         
            +
                MashedPostalWorker.validate_location  :suburb => {:accessor => :city, :message => "That doesn't match up!"},
         
     | 
| 
      
 61 
     | 
    
         
            +
                                                      :postcode => {:accessor => :zipcode, :message => ["Postcode %s cannot be found", :zipcode]},
         
     | 
| 
      
 62 
     | 
    
         
            +
                                                      :state => {:accessor => "state.name", :message => ["%s is such a better state anyway *ducks*", "state.name"]}
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
              
         
     | 
| 
      
 65 
     | 
    
         
            +
              it "should have a custom message on the suburb" do
         
     | 
| 
      
 66 
     | 
    
         
            +
                @worker = MashedPostalWorker.new({:city => "Annandale", :zipcode => 3001, :state => State.new(:name => "NSW")})
         
     | 
| 
      
 67 
     | 
    
         
            +
                @worker.should_not be_valid
         
     | 
| 
      
 68 
     | 
    
         
            +
                @worker.errors.on(:suburb).should eql("That doesn't match up!")
         
     | 
| 
      
 69 
     | 
    
         
            +
                @worker.errors.on(:state).should eql("NSW is such a better state anyway *ducks*")
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
              
         
     | 
| 
      
 72 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,55 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.join(File.dirname(__FILE__), "../spec_helper")
         
     | 
| 
      
 2 
     | 
    
         
            +
            include Auspost
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            describe Postie do
         
     | 
| 
      
 5 
     | 
    
         
            +
              include Postie
         
     | 
| 
      
 6 
     | 
    
         
            +
              
         
     | 
| 
      
 7 
     | 
    
         
            +
              it "should find Annandale and return true" do
         
     | 
| 
      
 8 
     | 
    
         
            +
                location?({:postcode => "2038", :suburb => "Annandale", :state => "NSW"}).status.should eql(true)
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
              
         
     | 
| 
      
 11 
     | 
    
         
            +
              it "shouldn't find that Surry Hills is in the 2000 postcode" do
         
     | 
| 
      
 12 
     | 
    
         
            +
                location?({:postcode => "2000", :suburb => "Surry Hills", :state => "QLD"}).status.should_not eql(true)
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
              
         
     | 
| 
      
 15 
     | 
    
         
            +
              # Testing this to ensure sub-strings don't pass as true
         
     | 
| 
      
 16 
     | 
    
         
            +
              it "shoudn't find dale in 2038" do
         
     | 
| 
      
 17 
     | 
    
         
            +
                location?({:postcode => "2038", :suburb => "dale", :state => "NSW"}).status.should_not eql(true)
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
              
         
     | 
| 
      
 20 
     | 
    
         
            +
              it "shouldn't substring search" do
         
     | 
| 
      
 21 
     | 
    
         
            +
                location?(:postcode => "2038", :suburb => "Annandale", :state => "N").status.should_not eql(true)
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
              
         
     | 
| 
      
 24 
     | 
    
         
            +
              it "should raise if there's not a postcode" do
         
     | 
| 
      
 25 
     | 
    
         
            +
                lambda { location?(:suburb => "Surry Hills", :state => "FOO") }.should raise_error(ArgumentError)
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
              
         
     | 
| 
      
 28 
     | 
    
         
            +
              it "should raise if there's not a suburb" do
         
     | 
| 
      
 29 
     | 
    
         
            +
                lambda { location?(:postcode => 2038, :state => "FOO") }.should raise_error(ArgumentError)
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
              
         
     | 
| 
      
 32 
     | 
    
         
            +
              it "should raise if there's not a state" do
         
     | 
| 
      
 33 
     | 
    
         
            +
                lambda { location?(:suburb => "Surry Hills", :postcode => 2038) }.should raise_error(ArgumentError)
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
              
         
     | 
| 
      
 36 
     | 
    
         
            +
              it "should accept an Integer for the postcode" do
         
     | 
| 
      
 37 
     | 
    
         
            +
                location?({:postcode => 2038, :suburb => "Annandale", :state => "NSW"}).status.should eql(true)
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
              
         
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            describe Postie, " with cached" do
         
     | 
| 
      
 43 
     | 
    
         
            +
              include Postie
         
     | 
| 
      
 44 
     | 
    
         
            +
              
         
     | 
| 
      
 45 
     | 
    
         
            +
              it "should cache a result" do
         
     | 
| 
      
 46 
     | 
    
         
            +
                @io = mock(IO)
         
     | 
| 
      
 47 
     | 
    
         
            +
                @string = mock(String)
         
     | 
| 
      
 48 
     | 
    
         
            +
                @array  = mock(Array)
         
     | 
| 
      
 49 
     | 
    
         
            +
                Postie::Cache.should_receive(:new).and_return(@io)
         
     | 
| 
      
 50 
     | 
    
         
            +
                @io.should_receive(:read).with("2038").and_return(@string)
         
     | 
| 
      
 51 
     | 
    
         
            +
                @string.should_receive(:map).at_least(:once).and_return(@array)
         
     | 
| 
      
 52 
     | 
    
         
            +
                @array.should_receive(:include?).with(true).and_return(true)
         
     | 
| 
      
 53 
     | 
    
         
            +
                location?({:postcode => "2038", :suburb => "Annandale", :state => "NSW"}).status.should eql(true)
         
     | 
| 
      
 54 
     | 
    
         
            +
              end  
         
     | 
| 
      
 55 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,187 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            <html>
         
     | 
| 
      
 3 
     | 
    
         
            +
            <head>
         
     | 
| 
      
 4 
     | 
    
         
            +
            <link rel="stylesheet" href="/include/stylesheet/miniapps.css" type="text/css">
         
     | 
| 
      
 5 
     | 
    
         
            +
            <link rel="stylesheet" href="/include/stylesheet/mainstyle.css" type="text/css">
         
     | 
| 
      
 6 
     | 
    
         
            +
            <title>Australia Post - Postcode Search</title>
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            <META NAME='ROBOTS' CONTENT='ALL'>
         
     | 
| 
      
 9 
     | 
    
         
            +
            <META NAME='description' CONTENT='Search for Australian Postcode locations online'>
         
     | 
| 
      
 10 
     | 
    
         
            +
            <META NAME='keywords' CONTENT='Australia Post Postcode Search Find locations'>
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            </head> 
         
     | 
| 
      
 13 
     | 
    
         
            +
            <script type="text/JavaScript">
         
     | 
| 
      
 14 
     | 
    
         
            +
            <!--
         
     | 
| 
      
 15 
     | 
    
         
            +
            function MM_preloadImages() { //v3.0
         
     | 
| 
      
 16 
     | 
    
         
            +
              var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
         
     | 
| 
      
 17 
     | 
    
         
            +
                var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
         
     | 
| 
      
 18 
     | 
    
         
            +
                if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
         
     | 
| 
      
 19 
     | 
    
         
            +
            } 
         
     | 
| 
      
 20 
     | 
    
         
            +
             
         
     | 
| 
      
 21 
     | 
    
         
            +
            function MM_swapImgRestore() { //v3.0 
         
     | 
| 
      
 22 
     | 
    
         
            +
              var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
         
     | 
| 
      
 23 
     | 
    
         
            +
            }
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            function MM_findObj(n, d) { //v4.01
         
     | 
| 
      
 26 
     | 
    
         
            +
              var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
         
     | 
| 
      
 27 
     | 
    
         
            +
                d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
         
     | 
| 
      
 28 
     | 
    
         
            +
              if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
         
     | 
| 
      
 29 
     | 
    
         
            +
              for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
         
     | 
| 
      
 30 
     | 
    
         
            +
              if(!x && d.getElementById) x=d.getElementById(n); return x;
         
     | 
| 
      
 31 
     | 
    
         
            +
            }
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            function MM_swapImage() { //v3.0
         
     | 
| 
      
 34 
     | 
    
         
            +
              var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
         
     | 
| 
      
 35 
     | 
    
         
            +
               if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
         
     | 
| 
      
 36 
     | 
    
         
            +
            }
         
     | 
| 
      
 37 
     | 
    
         
            +
            function cmdGo_Click() {    
         
     | 
| 
      
 38 
     | 
    
         
            +
            window.document.queryForm.submit(); }
         
     | 
| 
      
 39 
     | 
    
         
            +
            //-->
         
     | 
| 
      
 40 
     | 
    
         
            +
            </script> 
         
     | 
| 
      
 41 
     | 
    
         
            +
            <table width="780" border="0" cellspacing="0" cellpadding="0">
         
     | 
| 
      
 42 
     | 
    
         
            +
              <tr class="top-header">
         
     | 
| 
      
 43 
     | 
    
         
            +
                <td width="210"><a href="http://www.auspost.com.au"><img src="/auspost/images/display/logo.jpg" alt="Australia Post Home" width="182" height="45" border="0" /></a></td>
         
     | 
| 
      
 44 
     | 
    
         
            +
                <td><img src="/auspost/images/display/b_arrow.gif" alt="Arrow" id="contact-arrow" width="13" height="14" />  <a class="white-title" href="http://www.auspost.com.au/BCP/0,1080,CH3988%257EMO19,00.html">Jobs @ Post</a>   <img src="/auspost/images/display/b_arrow.gif" alt="Arrow" id="contact-arrow" width="13" height="14" />   <a class="white-title" href="http://www.auspost.com.au/CUP/0,,CHNONE%257EMO19,00.html">Contact Us</a>    <span class="search-title">Search Site :</span> <form id="queryForm" name="queryForm" action="http://search.auspost.com.au/cse/auspost/default.asp" method="get"><input id="queryBox" name="q" value="" size="20" />  <a href="javascript:onClick=cmdGo_Click();" onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('btngosearch','','/auspost/images/display/br_submit.gif',1)"><img name="btngosearch" id="btngosearch" src="/auspost/images/display/b_submit.gif" alt="submit" width="62" height="22" border="0" /></form></td>
         
     | 
| 
      
 45 
     | 
    
         
            +
              </tr>
         
     | 
| 
      
 46 
     | 
    
         
            +
            </table>
         
     | 
| 
      
 47 
     | 
    
         
            +
            <table width="780" border="0" cellspacing="0" cellpadding="0"> 
         
     | 
| 
      
 48 
     | 
    
         
            +
              <tr class="tabs-row">
         
     | 
| 
      
 49 
     | 
    
         
            +
                <td width="19"> </td>
         
     | 
| 
      
 50 
     | 
    
         
            +
                <td width="101"><a href="http://www.auspost.com.au"><img src="/auspost/images/display/b_Home.gif" alt="Home" name="Image2" width="82" height="29" border="0" id="Image2" onmouseover="MM_swapImage('Image2','','/auspost/images/display/br_Home.gif',1)" onmouseout="MM_swapImgRestore()" /></a></td>
         
     | 
| 
      
 51 
     | 
    
         
            +
                <td width="139"><a href="http://www.auspost.com.au/CAP/0,,CH2002%257EMO19,00.html"><img src="/auspost/images/display/b_GenServices.gif" alt="General Services" width="122" height="29" border="0" id="Image3" onmouseover="MM_swapImage('Image3','','/auspost/images/display/br_GenServices.gif',1)" onmouseout="MM_swapImgRestore()" /></a></td>
         
     | 
| 
      
 52 
     | 
    
         
            +
                <td width="199"><a href="http://www.auspost.com.au/CAP/0,,CH2006%257EMO19,00.html"><img src="/auspost/images/display/b_Billing.gif" alt="Billing & Financial" width="180" height="29" border="0" id="Image4" onmouseover="MM_swapImage('Image4','','/auspost/images/display/br_Billing.gif',1)" onmouseout="MM_swapImgRestore()" /></a></td>
         
     | 
| 
      
 53 
     | 
    
         
            +
                <td width="154"><a href="http://www.auspost.com.au/CAP/0,,CH2005%257EMO19,00.html"><img src="/auspost/images/display/b_BusSolutions.gif" alt="Business Solutions" width="138" height="29" border="0" id="Image5" onmouseover="MM_swapImage('Image5','','/auspost/images/display/br_BusSolutions.gif',1)" onmouseout="MM_swapImgRestore()" /></a></td>
         
     | 
| 
      
 54 
     | 
    
         
            +
                <td><a href="http://www.auspost.com.au/CAP/0,,CH2007%257EMO19,00.html"><img src="/auspost/images/display/b_AboutUs.gif" alt="About Us" width="85" height="29" border="0" id="Image6" onmouseover="MM_swapImage('Image6','','/auspost/images/display/br_AboutUs.gif',1)" onmouseout="MM_swapImgRestore()" /></a></td>
         
     | 
| 
      
 55 
     | 
    
         
            +
                <td width="50"><div align="right"><img src="/auspost/images/display/cnr_btm_r.gif" alt="corner" width="39" height="29" /></div></td>
         
     | 
| 
      
 56 
     | 
    
         
            +
              </tr>
         
     | 
| 
      
 57 
     | 
    
         
            +
              <tr>
         
     | 
| 
      
 58 
     | 
    
         
            +
                <td colspan="7"><img src="/auspost/images/display/transparent 3x3.gif" alt="Blank" width="8" height="8" /></td>
         
     | 
| 
      
 59 
     | 
    
         
            +
              </tr> 
         
     | 
| 
      
 60 
     | 
    
         
            +
            </table>
         
     | 
| 
      
 61 
     | 
    
         
            +
            <table border="0" cellpadding="0" cellspacing="0" width="780">
         
     | 
| 
      
 62 
     | 
    
         
            +
              <tr>
         
     | 
| 
      
 63 
     | 
    
         
            +
                <td valign="top" id="td-site-app">
         
     | 
| 
      
 64 
     | 
    
         
            +
                
         
     | 
| 
      
 65 
     | 
    
         
            +
            <ul id="site-apps" style="padding-right: 5px;">
         
     | 
| 
      
 66 
     | 
    
         
            +
              <li><img src="/auspost/images/display/h_Useful_Tools.gif" alt="Useful Tools" width="113" height="29" /></li>
         
     | 
| 
      
 67 
     | 
    
         
            +
              <li><img src="/auspost/images/display/i_FindPostcode.gif" alt="Find a postcode" width="22" height="22" />  <a class="min-apps" href="http://www1.auspost.com.au/postcodes/">Find a postcode</a></li>
         
     | 
| 
      
 68 
     | 
    
         
            +
                <li><img src="/auspost/images/display/i_CalcPostageRates.gif" alt="Calculate postage rates" width="22" height="22" />  <a class="min-apps" href="http://www1.auspost.com.au/pac/">Calculate postage rates</a></li>
         
     | 
| 
      
 69 
     | 
    
         
            +
                <li><img src="/auspost/images/display/i_ExpressPostPlatTrackg.gif" alt="Australia post delivery tracking" width="22" height="22" />  <a class="min-apps" href="http://www.auspost.com.au/track">Track my item</a></li>
         
     | 
| 
      
 70 
     | 
    
         
            +
                <li><img src="/auspost/images/display/i_FindPostalOutlet.gif" alt="Find a postal outlet" width="22" height="22" />  <a class="min-apps" href="http://www.auspost.com.au/pol/">Find a postal outlet</a></li>
         
     | 
| 
      
 71 
     | 
    
         
            +
              <li><img src="/auspost/images/display/i_FindPostalBox.gif" alt="Find a street posting box" width="22" height="22" />  <a class="min-apps" href="http://www.auspost.com.au/pol/">Find a street posting box</a></li>
         
     | 
| 
      
 72 
     | 
    
         
            +
                <li><img src="/auspost/images/display/i_PayBillsOnline.gif" alt="Pay bills online" width="22" height="22" />  <a class="min-apps" href="http://www.postbillpay.com.au/">Pay bills online</a></li>
         
     | 
| 
      
 73 
     | 
    
         
            +
                <li><img src="/auspost/images/display/i_IntnlPostageDetails.gif" alt="International Postage Details" width="22" height="22" />  <a class="min-apps" href="http://www1.auspost.com.au/international/">International postage details</a></li>
         
     | 
| 
      
 74 
     | 
    
         
            +
                <li><img src="/auspost/images/display/i_PostGuides.gif" alt="Post guides" width="22" height="22" />  <a class="min-apps" href="http://www.auspost.com.au/BCP/0,,CH3851%257EMO19,00.html">Post guides</a></li>
         
     | 
| 
      
 75 
     | 
    
         
            +
            </ul> 
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                </td>
         
     | 
| 
      
 78 
     | 
    
         
            +
            <td valign="top">
         
     | 
| 
      
 79 
     | 
    
         
            +
            <table width="600" border="0" cellpadding="0" cellspacing="10">
         
     | 
| 
      
 80 
     | 
    
         
            +
                    <tr valign="top">
         
     | 
| 
      
 81 
     | 
    
         
            +
                      <td width="493" align="center" valign="top"><font face="verdana,Helv,Arial" size="2">
         
     | 
| 
      
 82 
     | 
    
         
            +
                        
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            <table border="0" cellpadding="0" cellspacing="0" width="490">
         
     | 
| 
      
 85 
     | 
    
         
            +
              <tr>
         
     | 
| 
      
 86 
     | 
    
         
            +
                <!-- banner header -->
         
     | 
| 
      
 87 
     | 
    
         
            +
                <td colspan="2" bgcolor="#B9E3DE"><img src="../images_new/postcode_search/funct_postcodesearch.gif" alt="Postcode Search" width="327" height="32"></td>
         
     | 
| 
      
 88 
     | 
    
         
            +
              </tr>
         
     | 
| 
      
 89 
     | 
    
         
            +
              <tr>
         
     | 
| 
      
 90 
     | 
    
         
            +
                <!-- Results row -->
         
     | 
| 
      
 91 
     | 
    
         
            +
                <td width="330" valign="top"><table width="330" border="0" cellpadding="5" cellspacing="0">
         
     | 
| 
      
 92 
     | 
    
         
            +
                    
         
     | 
| 
      
 93 
     | 
    
         
            +
            <tr>
         
     | 
| 
      
 94 
     | 
    
         
            +
              <td valign="top" width="7" bgcolor="#ff0000"><font face="verdana, arial, helv" size="2" color="#ffffff"><strong>1.</strong></td>
         
     | 
| 
      
 95 
     | 
    
         
            +
              <td><font face="arial, helv" size="2"> <strong>LOCATION:</strong> ANNANDALE, NSW<br />
         
     | 
| 
      
 96 
     | 
    
         
            +
                
         
     | 
| 
      
 97 
     | 
    
         
            +
                <strong>POSTCODE:</strong> 2038<br />
         
     | 
| 
      
 98 
     | 
    
         
            +
                
         
     | 
| 
      
 99 
     | 
    
         
            +
                <strong>CATEGORY:</strong> Delivery Area<br />
         
     | 
| 
      
 100 
     | 
    
         
            +
                
         
     | 
| 
      
 101 
     | 
    
         
            +
              </td>
         
     | 
| 
      
 102 
     | 
    
         
            +
            </tr>
         
     | 
| 
      
 103 
     | 
    
         
            +
            <tr>
         
     | 
| 
      
 104 
     | 
    
         
            +
              <td colspan="2"><hr noshade size="1">
         
     | 
| 
      
 105 
     | 
    
         
            +
              </td>
         
     | 
| 
      
 106 
     | 
    
         
            +
            </tr>
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                  </table></td>
         
     | 
| 
      
 109 
     | 
    
         
            +
                <td width="150" valign="top" bgcolor="#B9E3DE"><table width="150" border="0" cellpadding="5" cellspacing="0">
         
     | 
| 
      
 110 
     | 
    
         
            +
                    <!-- Results summary table -->
         
     | 
| 
      
 111 
     | 
    
         
            +
                    <tr>
         
     | 
| 
      
 112 
     | 
    
         
            +
                      <!-- Show results for each state -->
         
     | 
| 
      
 113 
     | 
    
         
            +
                      <td width="150" style="background-color: #B9E3DE; font-size:100%"><a href="index.asp">Search Again</a>
         
     | 
| 
      
 114 
     | 
    
         
            +
                        <hr noshade size="1">
         
     | 
| 
      
 115 
     | 
    
         
            +
                        <strong>Returned Matches:</strong> 1
         
     | 
| 
      
 116 
     | 
    
         
            +
                        <hr noshade size="1">
         
     | 
| 
      
 117 
     | 
    
         
            +
                        
         
     | 
| 
      
 118 
     | 
    
         
            +
                        <strong>Breakdown</strong>
         
     | 
| 
      
 119 
     | 
    
         
            +
                        <br />New South Wales: 1
         
     | 
| 
      
 120 
     | 
    
         
            +
                      </td>
         
     | 
| 
      
 121 
     | 
    
         
            +
                    </tr>
         
     | 
| 
      
 122 
     | 
    
         
            +
                    
         
     | 
| 
      
 123 
     | 
    
         
            +
                  </table></td>
         
     | 
| 
      
 124 
     | 
    
         
            +
              </tr>
         
     | 
| 
      
 125 
     | 
    
         
            +
            </table>
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                      </td>
         
     | 
| 
      
 128 
     | 
    
         
            +
                    </tr>
         
     | 
| 
      
 129 
     | 
    
         
            +
                  </table>
         
     | 
| 
      
 130 
     | 
    
         
            +
                </td>  
         
     | 
| 
      
 131 
     | 
    
         
            +
              </tr>
         
     | 
| 
      
 132 
     | 
    
         
            +
            </table>
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
            <table width="780" border="0" cellspacing="0" cellpadding="0">
         
     | 
| 
      
 135 
     | 
    
         
            +
            <!---------- SPACER ------------------------------------------------------------------->
         
     | 
| 
      
 136 
     | 
    
         
            +
              <tr> 
         
     | 
| 
      
 137 
     | 
    
         
            +
                <td valign="top" height="20"> 
         
     | 
| 
      
 138 
     | 
    
         
            +
                </td>
         
     | 
| 
      
 139 
     | 
    
         
            +
              </tr>
         
     | 
| 
      
 140 
     | 
    
         
            +
            <!---------- end SPACER --------------------------------------------------------------->  
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
            <!---------- FIRST LEVEL NAVIGATION ------------------------------------------------------>
         
     | 
| 
      
 143 
     | 
    
         
            +
              <tr>
         
     | 
| 
      
 144 
     | 
    
         
            +
                <td id="td-foot"> 
         
     | 
| 
      
 145 
     | 
    
         
            +
                    <br /> 
         
     | 
| 
      
 146 
     | 
    
         
            +
                <ul id="footer-list">
         
     | 
| 
      
 147 
     | 
    
         
            +
                <li><img src="/auspost/images/display/a_right.gif" alt="Arrow" width="4" height="7" /> <a class="footer" href="http://www.auspost.com.au/APC/CDA/Sitemap/APC_CDA_Sitemap/0,1084,CHNONE%257EMO19,00.html">Site map</a>    </li>
         
     | 
| 
      
 148 
     | 
    
         
            +
                <li><img src="/auspost/images/display/a_right.gif" alt="Arrow" width="4" height="7" /> <a class="footer" href="http://www.auspost.com.au/CUP/0,1050,CHNONE%257EMO19,00.html">Contact Us</a>    </li>
         
     | 
| 
      
 149 
     | 
    
         
            +
                <li><img src="/auspost/images/display/a_right.gif" alt="Arrow" width="4" height="7" /> <a class="footer" href="http://www.auspost.com.au/APC/CDA/Site_Governance/APC_CDA_Privacy_Policy/">Privacy</a>    </li>
         
     | 
| 
      
 150 
     | 
    
         
            +
                <li><img src="/auspost/images/display/a_right.gif" alt="Arrow" width="4" height="7" /> <a class="footer" href="http://www.auspost.com.au/APC/CDA/Site_Governance/APC_CDA_Terms_Conditions/">Terms & Conditions </a></li>
         
     | 
| 
      
 151 
     | 
    
         
            +
              </ul>
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
            <!-- Track File Downloads with Google --> 
         
     | 
| 
      
 155 
     | 
    
         
            +
            <script language="javascript" type="text/javascript" src="/APC/CDA/CSS/gatag.js" ></script>
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
            <!--Google tracking --> 
         
     | 
| 
      
 158 
     | 
    
         
            +
            <script type="text/javascript">
         
     | 
| 
      
 159 
     | 
    
         
            +
              var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
         
     | 
| 
      
 160 
     | 
    
         
            +
              document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
         
     | 
| 
      
 161 
     | 
    
         
            +
            </script>
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
            <script type="text/javascript">
         
     | 
| 
      
 164 
     | 
    
         
            +
            <!-- Auspost roll up account --> 
         
     | 
| 
      
 165 
     | 
    
         
            +
              try {
         
     | 
| 
      
 166 
     | 
    
         
            +
                var APTracker = _gat._getTracker("UA-2225711-5");
         
     | 
| 
      
 167 
     | 
    
         
            +
                APTracker._setDomainName(".auspost.com.au");
         
     | 
| 
      
 168 
     | 
    
         
            +
                APTracker._trackPageview("WWW1" + document.location.pathname);
         
     | 
| 
      
 169 
     | 
    
         
            +
              } catch(err) {}
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
              <!-- Auspost account --> 
         
     | 
| 
      
 172 
     | 
    
         
            +
              try {
         
     | 
| 
      
 173 
     | 
    
         
            +
                var pageTracker = _gat._getTracker("UA-2225711-1");
         
     | 
| 
      
 174 
     | 
    
         
            +
                pageTracker._setDomainName(".auspost.com.au");
         
     | 
| 
      
 175 
     | 
    
         
            +
                pageTracker._trackPageview();
         
     | 
| 
      
 176 
     | 
    
         
            +
              } catch(err) {}
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
              <!-- WWW1 account --> 
         
     | 
| 
      
 179 
     | 
    
         
            +
              try {
         
     | 
| 
      
 180 
     | 
    
         
            +
                var pageTracker = _gat._getTracker("UA-2225711-3");
         
     | 
| 
      
 181 
     | 
    
         
            +
                pageTracker._setDomainName(".auspost.com.au");
         
     | 
| 
      
 182 
     | 
    
         
            +
                pageTracker._trackPageview();
         
     | 
| 
      
 183 
     | 
    
         
            +
              } catch(err) {}
         
     | 
| 
      
 184 
     | 
    
         
            +
            </script>
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
            </body>
         
     | 
| 
      
 187 
     | 
    
         
            +
            </html>
         
     | 
| 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            gem 'sqlite3-ruby'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'sqlite3'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'active_record'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ActiveRecord::Base.establish_connection(
         
     | 
| 
      
 6 
     | 
    
         
            +
               :adapter => "sqlite3",
         
     | 
| 
      
 7 
     | 
    
         
            +
               :database  => ":memory:"
         
     | 
| 
      
 8 
     | 
    
         
            +
             )
         
     | 
| 
      
 9 
     | 
    
         
            +
             ActiveRecord::Base.connection.create_table(:postal_workers) do |t|
         
     | 
| 
      
 10 
     | 
    
         
            +
               t.string :address
         
     | 
| 
      
 11 
     | 
    
         
            +
               t.string :postcode
         
     | 
| 
      
 12 
     | 
    
         
            +
               t.string :suburb
         
     | 
| 
      
 13 
     | 
    
         
            +
               t.string :state
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            ActiveRecord::Base.connection.create_table(:mashed_postal_workers) do |t|
         
     | 
| 
      
 18 
     | 
    
         
            +
              t.string :addr
         
     | 
| 
      
 19 
     | 
    
         
            +
              t.string :zipcode
         
     | 
| 
      
 20 
     | 
    
         
            +
              t.string :city
         
     | 
| 
      
 21 
     | 
    
         
            +
              t.integer :state_id
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            ActiveRecord::Base.connection.create_table(:states) do |t|
         
     | 
| 
      
 25 
     | 
    
         
            +
              t.string :name
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            class PostalWorker < ActiveRecord::Base;end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            class MashedPostalWorker < ActiveRecord::Base
         
     | 
| 
      
 32 
     | 
    
         
            +
              
         
     | 
| 
      
 33 
     | 
    
         
            +
              belongs_to :state
         
     | 
| 
      
 34 
     | 
    
         
            +
              
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            class State < ActiveRecord::Base
         
     | 
| 
      
 38 
     | 
    
         
            +
              has_many :mashed_postal_workers
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'spec'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib auspost]))
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Spec::Runner.configure do |config|
         
     | 
| 
      
 6 
     | 
    
         
            +
              # == Mock Framework
         
     | 
| 
      
 7 
     | 
    
         
            +
              #
         
     | 
| 
      
 8 
     | 
    
         
            +
              # RSpec uses it's own mocking framework by default. If you prefer to
         
     | 
| 
      
 9 
     | 
    
         
            +
              # use mocha, flexmock or RR, uncomment the appropriate line:
         
     | 
| 
      
 10 
     | 
    
         
            +
              #
         
     | 
| 
      
 11 
     | 
    
         
            +
              # config.mock_with :mocha
         
     | 
| 
      
 12 
     | 
    
         
            +
              # config.mock_with :flexmock
         
     | 
| 
      
 13 
     | 
    
         
            +
              # config.mock_with :rr
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,83 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: auspost
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.8.5
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Cameron Barrie
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2010-01-02 00:00:00 +11:00
         
     | 
| 
      
 13 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 14 
     | 
    
         
            +
            dependencies: 
         
     | 
| 
      
 15 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 16 
     | 
    
         
            +
              name: bones
         
     | 
| 
      
 17 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 18 
     | 
    
         
            +
              version_requirement: 
         
     | 
| 
      
 19 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 20 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 21 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 22 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 23 
     | 
    
         
            +
                    version: 3.2.0
         
     | 
| 
      
 24 
     | 
    
         
            +
                version: 
         
     | 
| 
      
 25 
     | 
    
         
            +
            description: |-
         
     | 
| 
      
 26 
     | 
    
         
            +
              Give you the ability to search the Australia Post Web site with either Suburb or Postcode, and return an array of Locations.
         
     | 
| 
      
 27 
     | 
    
         
            +
              Also add's validation methods to ActiveRecord Objects to allow you to validate that A Postcode + State + Suburb is correct
         
     | 
| 
      
 28 
     | 
    
         
            +
            email: camwritescode@gmail.com
         
     | 
| 
      
 29 
     | 
    
         
            +
            executables: 
         
     | 
| 
      
 30 
     | 
    
         
            +
            - auspost
         
     | 
| 
      
 31 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            extra_rdoc_files: 
         
     | 
| 
      
 34 
     | 
    
         
            +
            - History.txt
         
     | 
| 
      
 35 
     | 
    
         
            +
            - README.txt
         
     | 
| 
      
 36 
     | 
    
         
            +
            - bin/auspost
         
     | 
| 
      
 37 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 38 
     | 
    
         
            +
            - .bnsignore
         
     | 
| 
      
 39 
     | 
    
         
            +
            - History.txt
         
     | 
| 
      
 40 
     | 
    
         
            +
            - README.txt
         
     | 
| 
      
 41 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 42 
     | 
    
         
            +
            - bin/auspost
         
     | 
| 
      
 43 
     | 
    
         
            +
            - lib/auspost.rb
         
     | 
| 
      
 44 
     | 
    
         
            +
            - lib/auspost/active_record.rb
         
     | 
| 
      
 45 
     | 
    
         
            +
            - lib/auspost/active_record/validations.rb
         
     | 
| 
      
 46 
     | 
    
         
            +
            - lib/auspost/postie.rb
         
     | 
| 
      
 47 
     | 
    
         
            +
            - spec/auspost/active_record/validations_spec.rb
         
     | 
| 
      
 48 
     | 
    
         
            +
            - spec/auspost/postie_spec.rb
         
     | 
| 
      
 49 
     | 
    
         
            +
            - spec/fixtures/auspost.html
         
     | 
| 
      
 50 
     | 
    
         
            +
            - spec/fixtures/postal_worker.rb
         
     | 
| 
      
 51 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     | 
| 
      
 52 
     | 
    
         
            +
            has_rdoc: true
         
     | 
| 
      
 53 
     | 
    
         
            +
            homepage: http://www.camwritescode.com/auspost
         
     | 
| 
      
 54 
     | 
    
         
            +
            licenses: []
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 57 
     | 
    
         
            +
            rdoc_options: 
         
     | 
| 
      
 58 
     | 
    
         
            +
            - --main
         
     | 
| 
      
 59 
     | 
    
         
            +
            - README.txt
         
     | 
| 
      
 60 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 61 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 62 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 63 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 64 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 65 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 66 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 67 
     | 
    
         
            +
              version: 
         
     | 
| 
      
 68 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 69 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 70 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 71 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 72 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 73 
     | 
    
         
            +
              version: 
         
     | 
| 
      
 74 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            rubyforge_project: auspost
         
     | 
| 
      
 77 
     | 
    
         
            +
            rubygems_version: 1.3.5
         
     | 
| 
      
 78 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 79 
     | 
    
         
            +
            specification_version: 3
         
     | 
| 
      
 80 
     | 
    
         
            +
            summary: Give you the ability to search the Australia Post Web site with either Suburb or Postcode, and return an array of Locations
         
     | 
| 
      
 81 
     | 
    
         
            +
            test_files: 
         
     | 
| 
      
 82 
     | 
    
         
            +
            - spec/auspost/active_record/validations_spec.rb
         
     | 
| 
      
 83 
     | 
    
         
            +
            - spec/auspost/postie_spec.rb
         
     |