pax_global_header00006660000000000000000000000064127775510070014525gustar00rootroot0000000000000052 comment=21351eb89949ae0db32e67d41f24af80ab48dde4 business-us-usps-webtools-release-1.122/000077500000000000000000000000001277755100700202545ustar00rootroot00000000000000business-us-usps-webtools-release-1.122/.gitignore000066400000000000000000000003411277755100700222420ustar00rootroot00000000000000!Build/ *.bbproj *.bs *.o *.rej *.tar *.tar.gz *.tgz *.zip .last_cover_stats .prove /.build/ /MANIFEST.bak /META.* /MYMETA.* /Makefile /Makefile.old /blib/ /pm_to_blib Build Build.bat _build/ cover_db/ inc/ nytprof.out *.bak business-us-usps-webtools-release-1.122/.releaserc000066400000000000000000000001061277755100700222170ustar00rootroot00000000000000cpan_user BDFOY sf_user comdog sf_group_id 36221 sf_package_id 204029 business-us-usps-webtools-release-1.122/.travis.yml000066400000000000000000000007421277755100700223700ustar00rootroot00000000000000sudo: false language: perl perl: - "5.8" - "5.10" - "5.12" - "5.14" - "5.16" - "5.18" - "5.20" - "5.22" before_install: - git clone git://github.com/travis-perl/helpers ~/travis-perl-helpers - source ~/travis-perl-helpers/init --auto install: - cpanm --quiet --installdeps --notest . - cpanm --quiet --notest Devel::Cover::Report::Coveralls script: - cover -delete && cover -test after_success: - cover -report coveralls business-us-usps-webtools-release-1.122/Changes000066400000000000000000000023401277755100700215460ustar00rootroot00000000000000Revision history for Perl module Business::US::USPS::WebTools 1.122 2016-10-13T00:13:29Z * Another release because the last one wasn't indexed. ADOPTME has permissions on it. 1.121 2016-06-07T19:29:22Z * Bump to release version 1.12_01 2016-01-07T04:27:51Z * Add the Track & Confirm API 1.12 2015-09-29T19:45:43Z * Update for the latest API changes and test responses * Get DeliveryPoint, CarrierRoute, and ReturnText fields 1.11 - 2007-11-03 * cleanups to move from CVS to SVN * now requires perl 5.6 * cleanups to the disto; no need to upgrade if you already have this 0.00 - 2007-10-25 * distro adjustments. no big whoop. 1.09 - 2007-02-05 * Jay Buffington noted I wasn't escaping the query strings correctly (meaning, at all), so I fixed that. * This is an important fix that everyone should upgrade too. 1.06 - 2007-01-10 * First official release :) 0.10 - 2006-09-26 * Changed namespace to Business::US::USPS::* * More docs to point out you need the USPS UserID to use any of this * See http://www.usps.com/webtools/ 0.10 - 2006-09-16 * This is the initial release of a group of modules which implement the web services of the US Postal Service. This isn't screen scraping! * See http://www.usps.com/webtools/ business-us-usps-webtools-release-1.122/INSTALL.SKIP000066400000000000000000000001561277755100700220540ustar00rootroot00000000000000README\.pod README.* # things that might be in local directories after fooling # around with them \.DS_Store business-us-usps-webtools-release-1.122/LICENSE000066400000000000000000000174231277755100700212700ustar00rootroot00000000000000The Business::US::USPS::WebTools module is licensed under the same terms as perl itself, under the Artistic License 2.0. Artistic License 2.0 Copyright (c) 2000-2006, The Perl Foundation. http://www.perlfoundation.org/artistic_license_2_0 Preamble This license establishes the terms under which a given free software Package may be copied, modified, distributed, and/or redistributed. The intent is that the Copyright Holder maintains some artistic control over the development of that Package while still keeping the Package available as open source and free software. You are always permitted to make arrangements wholly outside of this license directly with the Copyright Holder of a given Package. If the terms of this license do not permit the full use that you propose to make of the Package, you should contact the Copyright Holder and seek a different licensing arrangement. Definitions "Copyright Holder" means the individual(s) or organization(s) named in the copyright notice for the entire Package. "Contributor" means any party that has contributed code or other material to the Package, in accordance with the Copyright Holder's procedures. "You" and "your" means any person who would like to copy, distribute, or modify the Package. "Package" means the collection of files distributed by the Copyright Holder, and derivatives of that collection and/or of those files. A given Package may consist of either the Standard Version, or a Modified Version. "Distribute" means providing a copy of the Package or making it accessible to anyone else, or in the case of a company or organization, to others outside of your company or organization. "Distributor Fee" means any fee that you charge for Distributing this Package or providing support for this Package to another party. It does not mean licensing fees. "Standard Version" refers to the Package if it has not been modified, or has been modified only in ways explicitly requested by the Copyright Holder. "Modified Version" means the Package, if it has been changed, and such changes were not explicitly requested by the Copyright Holder. "Original License" means this Artistic License as Distributed with the Standard Version of the Package, in its current version or as it may be modified by The Perl Foundation in the future. "Source" form means the source code, documentation source, and configuration files for the Package. "Compiled" form means the compiled bytecode, object code, binary, or any other form resulting from mechanical transformation or translation of the Source form. Permission for Use and Modification Without Distribution (1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version. Permissions for Redistribution of the Standard Version (2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package. (3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License. Distribution of Modified Versions of the Package as Source (4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following: (a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version. (b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version. (c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under (i) the Original License or (ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed. Distribution of Compiled Forms of the Standard Version or Modified Versions without the Source (5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. Such instructions must be valid at the time of your distribution. If these instructions, at any time while you are carrying out such distribution, become invalid, you must provide new instructions on demand or cease further distribution. If you provide valid instructions or cease distribution within thirty days after you become aware that the instructions are invalid, then you do not forfeit any of your rights under this license. (6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version. Aggregating or Linking the Package (7) You may aggregate the Package (either the Standard Version or Modified Version) with other packages and Distribute the resulting aggregation provided that you do not charge a licensing fee for the Package. Distributor Fees are permitted, and licensing fees for other components in the aggregation are permitted. The terms of this license apply to the use and Distribution of the Standard or Modified Versions as included in the aggregation. (8) You are permitted to link Modified and Standard Versions with other works, to embed the Package in a larger work of your own, or to build stand-alone binary or bytecode versions of applications that include the Package, and Distribute the result without restriction, provided the result does not expose a direct interface to the Package. Items That are Not Considered Part of a Modified Version (9) Works (including, but not limited to, modules and scripts) that merely extend or make use of the Package, do not, by themselves, cause the Package to be a Modified Version. In addition, such works are not considered parts of the Package itself, and are not subject to the terms of this license. General Provisions (10) Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license. (11) If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license. (12) This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder. (13) This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation business-us-usps-webtools-release-1.122/MANIFEST000066400000000000000000000010761277755100700214110ustar00rootroot00000000000000Changes examples/address_standardization.pl examples/track.pl examples/zip_code_lookup.pl INSTALL.SKIP lib/Business/US/USPS/WebTools.pm lib/Business/US/USPS/WebTools/AddressStandardization.pm lib/Business/US/USPS/WebTools/CityStateLookup.pm lib/Business/US/USPS/WebTools/TrackConfirm.pm lib/Business/US/USPS/WebTools/ZipCodeLookup.pm LICENSE Makefile.PL MANIFEST This list of files MANIFEST.SKIP README.pod t/address_verification.t t/city_state_lookup.t t/load.t t/pod.t t/pod_coverage.t t/test_manifest t/test_or_live.t t/track_confirm.t t/zip_code_lookup.t xt/changes.t business-us-usps-webtools-release-1.122/MANIFEST.SKIP000066400000000000000000000022411277755100700221510ustar00rootroot00000000000000 #!start included /usr/local/perls/perl-5.22.0/lib/5.22.0/ExtUtils/MANIFEST.SKIP # Avoid version control files. \bRCS\b \bCVS\b \bSCCS\b ,v$ \B\.svn\b \B\.git\b \B\.gitignore\b \b_darcs\b \B\.cvsignore$ # Avoid VMS specific MakeMaker generated files \bDescrip.MMS$ \bDESCRIP.MMS$ \bdescrip.mms$ # Avoid Makemaker generated and utility files. \bMANIFEST\.bak \bMakefile$ \bblib/ \bMakeMaker-\d \bpm_to_blib\.ts$ \bpm_to_blib$ \bblibdirs\.ts$ # 6.18 through 6.25 generated this \b_eumm/ # 7.05_05 and above # Avoid Module::Build generated and utility files. \bBuild$ \b_build/ \bBuild.bat$ \bBuild.COM$ \bBUILD.COM$ \bbuild.com$ # and Module::Build::Tiny generated files \b_build_params$ # Avoid temp and backup files. ~$ \.old$ \#$ \b\.# \.bak$ \.tmp$ \.# \.rej$ \..*\.sw.?$ # Avoid OS-specific files/dirs # Mac OSX metadata \B\.DS_Store # Mac OSX SMB mount metadata files \B\._ # Avoid Devel::Cover and Devel::CoverX::Covered files. \bcover_db\b \bcovered\b # Avoid prove files \B\.prove$ # Avoid MYMETA files ^MYMETA\. #!end included /usr/local/perls/perl-5.22.0/lib/5.22.0/ExtUtils/MANIFEST.SKIP \.releaserc \.lwpcookies \.travis\.yml t/\d t/env.t business-us-usps-webtools-release-1.122/Makefile.PL000066400000000000000000000062701277755100700222330ustar00rootroot00000000000000package Business::US::USPS::WebTools; use strict; use warnings; =encoding utf8 =head1 The build file for Business::US::USPS::WebTools This build file is a modulino; it works as both a build script and a module. To build the distribution, run this file normally: % perl Makefile.PL But, it's more interesting than that. You can load it with C and call C to get the data structure it passes to C: my $package = require '/path/to/Makefile.PL'; my $arguments = $package->arguments; Note that C-ing a file makes an entry in C<%INC> for exactly that name. If you try to C another file with the same name, even from a different path, C thinks it has already loaded the file. As such, I recommend you always require the full path to the file. The return value of the C is a package name (in this case, the name of the main module). Use that to call the C method. Even if this distribution needs a higher version of Perl, this bit only needs v5.8. You can play with the data structure with a primitive Perl. =cut print <<"HERE" unless( $ENV{USPS_WEBTOOLS_USERID} and $ENV{USPS_WEBTOOLS_PASSWORD} ); ---------------------------------------------------------------------------- To use these modules, you need a User ID and Password from the US Postal Service. See the USPS website for details: http://www.usps.com/webtools/htm/Address-Information.htm Set the USPS_WEBTOOLS_USERID and USPS_WEBTOOLS_PASSWORD environment variables. ---------------------------------------------------------------------------- HERE use File::Spec::Functions qw(catfile); my $module = __PACKAGE__; ( my $dist = $module ) =~ s/::/-/g; my $github = 'https://github.com/briandfoy/business-us-usps-webtools'; my $main_file = catfile( 'lib', split /::/, "$module.pm" ); my %WriteMakefile = ( 'MIN_PERL_VERSION' => '5.010', 'NAME' => $module, 'VERSION_FROM' => $main_file, 'ABSTRACT_FROM' => $main_file, 'LICENSE' => 'perl', 'AUTHOR' => 'brian d foy ', 'CONFIGURE_REQUIRES' => { 'ExtUtils::MakeMaker' => '6.64', 'File::Spec::Functions' => '0', }, 'BUILD_REQUIRES' => { }, 'TEST_REQUIRES' => { 'Test::More' => '0.98', }, 'PREREQ_PM' => { 'Hash::AsObject' => '0', 'LWP::Simple' => '0', 'URI' => '0', }, 'META_MERGE' => { 'meta-spec' => { version => 2 }, resources => { repository => { type => 'git', url => "$github.git", web => $github, }, bugtracker => { web => "$github/issues", }, homepage => $github, }, }, clean => { FILES => "$dist-*" }, ); sub arguments { \%WriteMakefile } do_it() unless caller; sub do_it { require File::Spec; my $MM ='ExtUtils::MakeMaker'; my $MM_version = eval{ "$MM " . $WriteMakefile{'CONFIGURE_REQUIRES'}{'ExtUtils::MakeMaker'} } || "$MM 6.64"; eval "use $MM_version; 1" or die "Could not load $MM_version: $@"; eval "use Test::Manifest 1.21" if -e File::Spec->catfile( qw(t test_manifest) ); my $arguments = arguments(); my $minimum_perl = $arguments->{MIN_PERL_VERSION} || '5.008'; eval "require $minimum_perl;" or die $@; WriteMakefile( %$arguments ); } no warnings; __PACKAGE__; business-us-usps-webtools-release-1.122/README.pod000066400000000000000000000077441277755100700217310ustar00rootroot00000000000000=pod =encoding utf8 =for HTML =for HTML Coverage Status =for HTML =for HTML =head1 The Business::US::USPS::WebTools module This is the I for the L Perl module. You're probably looking at this because you don't know where else to find what you're looking for. Read this once and you might never have to read one again for any Perl module. =head2 Documentation To read about L, look at the embedded documentation in the module itself. Inside the distribution, you can format it with L: % perldoc lib/Business/US/USPS/WebTools.pm If you have already installed the module, you can specify the module name instead of the file location: % perldoc Business::US::USPS::WebTools You can read the documentation and inspect the meta data on one of the CPAN web interfaces, such as L or L: =over 4 =item * L =item * L =back The standard module documentation has example uses in the SYNOPSIS section, but you can also look in the I directory (if it's there), or look at the test files in I. =head2 Installation You can install this module with a CPAN client, which will resolve and install the dependencies: % cpan Business::US::USPS::WebTools % cpanm Business::US::USPS::WebTools You can also install directly from the distribution directory, which will also install the dependencies: % cpan . % cpanm . You could install just this module manually: % perl Makefile.PL % make % make test % make install You probably don't want to do that unless you're fiddling with the module and only want to run the tests without installing anything. =head2 Source location The meta data, such as the source repository and bug tracker, is in I or the I files it creates. You can find that on those CPAN web interfaces, but you can also look at files directly in the source repository: =over 4 =item * L =back If you find a problem, file a ticket in the L: =over 4 =item * L =back =head2 Getting help Although I'm happy to hear from module users in private email, that's the best way for me to forget to do something. Besides the issue trackers, you can find help at L or L, both of which have many competent Perlers who can answer your question, almost in real time. They might not know the particulars of this module, but they can help you diagnose your problem. You might like to read L. =head2 Copyright and License You should have received a I file, but the license is also noted in the module files. About the only thing you can't do is pretend that you wrote code that you didn't. =head2 Good luck! Enjoy, brian d foy, bdfoy@cpan.org =cut business-us-usps-webtools-release-1.122/examples/000077500000000000000000000000001277755100700220725ustar00rootroot00000000000000business-us-usps-webtools-release-1.122/examples/address_standardization.pl000066400000000000000000000017261277755100700273400ustar00rootroot00000000000000#!/usr/bin/perl use Business::US::USPS::WebTools::AddressStandardization; my $verifier = Business::US::USPS::WebTools::AddressStandardization->new( { UserID => $ENV{USPS_WEBTOOLS_USERID}, Password => $ENV{USPS_WEBTOOLS_PASSWORD}, # Testing => 1, } ); my $address1 = prompt( "Address1" ); my $address2 = prompt( "Address2" ); my $city = prompt( "City" ); my $state = prompt( "State" ); my $zip5 = prompt( "Zip Code" ); my $hash = $verifier->verify_address( FirmName => '', Address1 => $address1, Address2 => $address2, City => $city, State => $state, Zip5 => $zip5, Zip4 => '', ); if( $verifier->is_error ) { warn "Oops!\n"; print $verifier->response; print "\n"; } else { print <<"HERE"; $hash->{FirmName} $hash->{Address1} $hash->{Address2} $hash->{City} $hash->{State} $hash->{Zip5} $hash->{Zip4} HERE } sub prompt { my $prompt = shift; print "$prompt > "; my $line = ; chomp( $line ); $line; }business-us-usps-webtools-release-1.122/examples/track.pl000066400000000000000000000007541277755100700235410ustar00rootroot00000000000000#!perl use v5.10; use Data::Dumper; use Business::US::USPS::WebTools::TrackConfirm; my $tracker = Business::US::USPS::WebTools::TrackConfirm->new( { UserID => $ENV{USPS_WEBTOOLS_USERID}, Password => $ENV{USPS_WEBTOOLS_PASSWORD}, # Testing => 1, } ); say "ARGV is @ARGV"; my $tracking_number = $tracker->is_valid_tracking_number( $ARGV[0] ); say "Tracking number is $tracking_number"; my $data = $tracker->track( TrackID => $ARGV[0] ); say $tracker->response; say Dumper( $data ); business-us-usps-webtools-release-1.122/examples/zip_code_lookup.pl000066400000000000000000000015511277755100700256160ustar00rootroot00000000000000#!/usr/bin/perl use Business::US::USPS::WebTools::ZipCodeLookup; my $verifier = Business::US::USPS::WebTools::ZipCodeLookup->new( { UserID => $ENV{USPS_WEBTOOLS_USERID}, Password => $ENV{USPS_WEBTOOLS_PASSWORD}, # Testing => 1, } ); my $address2 = prompt( "Address2" ); my $city = prompt( "City" ); my $state = prompt( "State" ); my $hash = $verifier->lookup_zipcode( FirmName => '', Address1 => $address1, Address2 => $address2, City => $city, State => $state, Zip5 => $zip5, Zip4 => '', ); if( $verifier->is_error ) { warn "Oops!\n"; print $verifier->response; print "\n"; } else { print <<"HERE"; $hash->{FirmName} $hash->{Address1} $hash->{Address2} $hash->{City} $hash->{State} $hash->{Zip5} $hash->{Zip4} HERE } sub prompt { my $prompt = shift; print "$prompt > "; my $line = ; chomp( $line ); $line; } business-us-usps-webtools-release-1.122/lib/000077500000000000000000000000001277755100700210225ustar00rootroot00000000000000business-us-usps-webtools-release-1.122/lib/Business/000077500000000000000000000000001277755100700226155ustar00rootroot00000000000000business-us-usps-webtools-release-1.122/lib/Business/US/000077500000000000000000000000001277755100700231445ustar00rootroot00000000000000business-us-usps-webtools-release-1.122/lib/Business/US/USPS/000077500000000000000000000000001277755100700237365ustar00rootroot00000000000000business-us-usps-webtools-release-1.122/lib/Business/US/USPS/WebTools.pm000066400000000000000000000125001277755100700260300ustar00rootroot00000000000000use v5.10; use utf8; package Business::US::USPS::WebTools; use strict; no warnings 'uninitialized'; use Carp qw(croak); use subs qw(); use vars qw($VERSION); $VERSION = '1.122'; =encoding utf8 =head1 NAME Business::US::USPS::WebTools - Use the US Postal Service Web Tools =head1 SYNOPSIS use Business::US::USPS::WebTools; # see subclasses for API details =head1 DESCRIPTION *** THIS IS ALPHA SOFTWARE *** This is the base class for the WebTools web service from the US Postal Service. The USPS offers several services, and this module handles the parts common to all of them: making the request, getting the response, parsing error reponses, and so on. The interesting stuff happens in one of the subclasses which implement a particular service. So far, the only subclass in this distribution is C. =over =cut my $LiveServer = "production.shippingapis.com"; my $TestServer = "testing.shippingapis.com"; =item new( ANONYMOUS_HASH ) Make the web service object. Pass is an anonymous hash with these keys: UserID the user id provided by the USPS Password the password provided by the USPS Testing true or false, to select the right server If you don't pass the UserID or Password entries, C looks in the environment variables USPS_WEBTOOLS_USERID and USPS_WEBTOOLS_PASSWORD. If C cannot find both the User ID and the Password, it croaks. If you pass a true value with the Testing key, the object will use the testing server host name and the testing URL path. If the Testing key is false or not present, the object uses the live server details. =cut sub new { my( $class, $args ) = @_; my $user_id = $args->{UserID} || $ENV{USPS_WEBTOOLS_USERID} || croak "No user ID for USPS WebTools!"; my $password = $args->{Password} || $ENV{USPS_WEBTOOLS_PASSWORD} || croak "No password for USPS WebTools!"; $args->{UserID} = $user_id; $args->{Password} = $password; $args->{testing} = $args->{Testing} || 0; $args->{live} = ! $args->{Testing}; bless $args, $class; } sub _testing { $_[0]->{testing} } sub _live { $_[0]->{live} } =item userid Returns the User ID for the web service. You need to get this from the US Postal Service. =item password Returns the Password for the web service. You need to get this from the US Postal Service. =item url Returns the URL for the request to the web service. So far, all requests are GET request with all of the data in the query string. =item response Returns the response from the web service. This is the slightly modified response. So far it only fixes up line endings and normalizes some error output for inconsistent responses from different physical servers. =cut sub userid { $_[0]->{UserID} } sub password { $_[0]->{Password} } sub url { $_[0]->{url} || $_[0]->_make_url } sub response { $_[0]->{response} } sub _api_host { my $self = shift; if( $self->_testing ) { $TestServer } elsif( $self->_live ) { $LiveServer } else { die "Am I testing or live?" } } sub _api_path { $_[0]->_live ? "/ShippingAPI.dll" : "/ShippingAPITest.dll" } sub _make_query_string { require URI; my( $self, $hash ) = @_; my $xml = $self->_make_query_xml( $hash ); my $uri = URI->new; $uri->query_form( API => $self->_api_name, XML => $xml, ); $uri->query; # this should work, but doesn't } sub _make_url { my( $self, $hash ) = @_; $self->{url} = qq|http://| . $self->_api_host . $self->_api_path . "?" . $self->_make_query_string( $hash ); } sub _make_request { my( $self, $url ) = @_; require LWP::Simple; $self->{error} = undef; $self->{response} = LWP::Simple::get( $self->url ); $self->{response} =~ s/\015\012/\n/g; $self->is_error; use Data::Dumper; # print STDERR "In _make_request:\n" . Dumper( $self ) . "\n"; $self->{response}; } =item is_error Returns true if the response to the last request was an error, and false otherwise. If the response was an error, this method sets various fields in the object: $self->{error}{number} $self->{error}{source} $self->{error}{description} $self->{error}{help_file} $self->{error}{help_context} =cut sub is_error { my $self = shift; return 0 unless $self->response =~ ""; $self->{error} = {}; # Apparently not all servers return this string in the # same way. Some have SOL and some have SoL $self->{response} =~ s/SOLServer/SOLServer/ig; ( $self->{error}{number} ) = $self->response =~ m|(-?\d+)|g; ( $self->{error}{source} ) = $self->response =~ m|(.*?)|g; ( $self->{error}{description} ) = $self->response =~ m|(.*?)|g; ( $self->{error}{help_file} ) = $self->response =~ m|(.*?)|ig; ( $self->{error}{help_context} ) = $self->response =~ m|(.*?)|ig; 1; } =back =head1 SEE ALSO The WebTools API is documented on the US Postal Service's website: http://www.usps.com/webtools/htm/Address-Information.htm =head1 SOURCE AVAILABILITY This source is in GitHub: https://github.com/briandfoy/business-us-usps-webtools =head1 AUTHOR brian d foy, C<< >> =head1 COPYRIGHT AND LICENSE Copyright © 2006-2016, brian d foy . All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; business-us-usps-webtools-release-1.122/lib/Business/US/USPS/WebTools/000077500000000000000000000000001277755100700254745ustar00rootroot00000000000000business-us-usps-webtools-release-1.122/lib/Business/US/USPS/WebTools/AddressStandardization.pm000066400000000000000000000075321277755100700325050ustar00rootroot00000000000000use v5.10; use utf8; package Business::US::USPS::WebTools::AddressStandardization; use strict; no warnings 'uninitialized'; use parent qw(Business::US::USPS::WebTools); use subs qw(); use vars qw($VERSION); $VERSION = '1.122'; =encoding utf8 =head1 NAME Business::US::USPS::WebTools::AddressStandardization - canonicalize a US address =head1 SYNOPSIS use Business::US::USPS::WebTools::AddressStandardization; my $verifier = Business::US::USPS::WebTools::AddressStandardization->new( { UserID => $ENV{USPS_WEBTOOLS_USERID}, Password => $ENV{USPS_WEBTOOLS_PASSWORD}, Testing => 1, } ); my $hash = $verifier->verify_address( FirmName => '', Address1 => '', Address2 => '6406 Ivy Lane', City => 'Greenbelt', State => 'MD', Zip5 => '', Zip4 => '', ); if( $verifier->is_error ) { warn "Oh No! $verifier->{error}{description}\n"; } else { print join "\n", map { "$_: $hash->{$_}" } qw(FirmName Address1 Address2 City State Zip5 Zip4 DeliveryPoint CarrierRoute ReturnText); } =head1 DESCRIPTION *** THIS IS ALPHA SOFTWARE *** This module implements the Address Standardization web service from the US Postal Service. It is a subclass of Business::US::USPS::WebTools. =cut =over 4 =cut sub _fields { qw( FirmName Address1 Address2 City State Zip5 Zip4 ) } sub _required { qw( Address2 City State ) } sub _response { (_fields(), qw( DeliveryPoint CarrierRoute ReturnText )) } =item verify_address( KEY, VALUE, ... ) The C method takes the following keys, which come directly from the USPS web service interface: FirmName The name of the company Address1 The suite or apartment Address2 The street address City The name of the city State The two letter state abbreviation Zip5 The 5 digit ZIP code Zip4 The 4 digit extension to the ZIP code It returns an anonymous hash with the same keys, but the values are the USPS's canonicalized address, plus three additional keys: DeliveryPoint The 2 digit extension to the ZIP+4 code CarrierRoute The 4 character postal carrier route ReturnText An error message when multiple addresses are found If there is an error, the hash values will be the empty string, and the error flag is set. Check is with C: $verifier->is_error; See the C documentation in Business::US::USPS::WebTools for more details on error information. =cut sub verify_address { my( $self, %hash ) = @_; $self->_make_url( \%hash ); $self->_make_request; $self->_parse_response; } sub _api_name { "Verify" } sub _make_query_xml { my( $self, $hash ) = @_; my $user = $self->userid; my $pass = $self->password; my $xml = qq|| . qq|true| . qq|true| . qq|
|; foreach my $field ( $self->_fields ) { $xml .= "<$field>$$hash{$field}"; } $xml .= qq|
|; return $xml; } sub _parse_response { my( $self ) = @_; #require 'Hash::AsObject'; my %hash = (); foreach my $field ( $self->_response ) { my( $value ) = $self->response =~ m|<$field>(.*?)|g; $hash{$field} = $value || ''; } bless \%hash, ref $self; # 'Hash::AsObject'; } =back =head1 TO DO =head1 SEE ALSO L The WebTools API is documented on the US Postal Service's website: https://www.usps.com/business/web-tools-apis/address-information-api.pdf =head1 SOURCE AVAILABILITY This source is in GitHub: https://github.com/briandfoy/business-us-usps-webtools =head1 AUTHOR brian d foy, C<< >> =head1 COPYRIGHT AND LICENSE Copyright © 2006-2016, brian d foy . All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; business-us-usps-webtools-release-1.122/lib/Business/US/USPS/WebTools/CityStateLookup.pm000066400000000000000000000063461277755100700311460ustar00rootroot00000000000000use v5.10; use utf8; package Business::US::USPS::WebTools::CityStateLookup; use strict; no warnings 'uninitialized'; use parent qw(Business::US::USPS::WebTools); use subs qw(); use vars qw($VERSION); $VERSION = '1.122'; =encoding utf8 =head1 NAME Business::US::USPS::WebTools::CityStateLookup - lookup a City and State by Zip Code =head1 SYNOPSIS use Business::US::USPS::WebTools::AddressStandardization; my $looker_upper = Business::US::USPS::WebTools::CityStateLookup->new( { UserID => $ENV{USPS_WEBTOOLS_USERID}, Password => $ENV{USPS_WEBTOOLS_PASSWORD}, Testing => 1, } ); my $hash = $looker_upper->lookup_city_state( ); if( $looker_upper->is_error ) { warn "Oh No! $looker_upper->{error}{description}\n"; } else { print join "\n", map { "$_: $hash->{$_}" } qw(FirmName Address1 Address2 City State Zip5 Zip4); } =head1 DESCRIPTION *** THIS IS ALPHA SOFTWARE *** This module implements the Address Standardization web service from the US Postal Service. It is a subclass of Business::US::USPS::WebTools. =cut =over 4 =cut sub _fields { qw( FirmName Address1 Address2 City State Zip5 Zip4 ) } sub _required { qw( Address2 City State ) } =item lookup_city_state( KEY, VALUE, ... ) The C method takes the following keys, which come directly from the USPS web service interface: FirmName The name of the company Address1 The suite or apartment Address2 The street address City The name of the city State The two letter state abbreviation Zip5 The 5 digit zip code Zip4 The 4 digit extension to the zip code It returns an anonymous hash with the same keys, but the values are the USPS's canonicalized address. If there is an error, the hash values will be the empty string, and the error flag is set. Check is with C: $verifier->is_error; See the C documentation in Business::US::USPS::WebTools for more details on error information. =cut sub lookup_city_state { my( $self, $zip_code ) = @_; $self->_make_url( { Zip5 => $zip_code } ); $self->_make_request; $self->_parse_response; } sub _api_name { "CityStateLookup" } sub _make_query_xml { my( $self, $hash ) = @_; my $user = $self->userid; my $pass = $self->password; my $xml = qq|| . qq|$$hash{Zip5}| . qq||; } sub _parse_response { my( $self ) = @_; #require 'Hash::AsObject'; my %hash = (); foreach my $field ( $self->_fields ) { my( $value ) = $self->response =~ m|<$field>(.*?)|g; $hash{$field} = $value || ''; } bless \%hash, ref $self; # 'Hash::AsObject'; } =back =head1 TO DO =head1 SEE ALSO L The WebTools API is documented on the US Postal Service's website: https://www.usps.com/business/web-tools-apis/address-information-api.pdf =head1 SOURCE AVAILABILITY This source is in GitHub: https://github.com/briandfoy/business-us-usps-webtools =head1 AUTHOR brian d foy, C<< >> =head1 COPYRIGHT AND LICENSE Copyright © 2006-2016, brian d foy . All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; business-us-usps-webtools-release-1.122/lib/Business/US/USPS/WebTools/TrackConfirm.pm000066400000000000000000000155231277755100700304220ustar00rootroot00000000000000use v5.10; use utf8; package Business::US::USPS::WebTools::TrackConfirm; use strict; no warnings 'uninitialized'; use parent qw(Business::US::USPS::WebTools); use subs qw(); use vars qw($VERSION); use Carp qw(croak carp); $VERSION = '1.122'; =encoding utf8 =head1 NAME Business::US::USPS::WebTools::TrackConfirm - track a shipment using the USPS Web Tools =head1 SYNOPSIS use Business::US::USPS::WebTools::TrackConfirm; my $tracker = Business::US::USPS::WebTools::TrackConfirm->new( { UserID => $ENV{USPS_WEBTOOLS_USERID}, Password => $ENV{USPS_WEBTOOLS_PASSWORD}, Testing => 1, } ); my $hash = $tracker->track( ); if( $tracker->is_error ) { warn "Oh No! $tracker->{error}{description}\n"; } else { print join "\n", map { "$_: $hash->{$_}" } qw(FirmName Address1 Address2 City State Zip5 Zip4); } =head1 DESCRIPTION *** THIS IS ALPHA SOFTWARE *** This module implements the Track & Confirm web service from the US Postal Service. It is a subclass of Business::US::USPS::WebTools. =cut =over 4 =cut sub _fields { qw( TrackID DestinationZipCode MailingDate ClientIp SourceId ) } sub _required { qw( TrackID ) } =item track( KEY, VALUE, ... ) The C method takes the following keys, which come directly from the USPS web service interface: TrackID The tracking number It returns an anonymous hash with the data from the response. Although the USPS API allows to make multiple queries in a single request, this method one queries one. If you want to see if something went wrong, check: $tracker->is_error; See the C documentation in Business::US::USPS::WebTools for more details on error information. =cut sub track { my( $self, %hash ) = @_; say Dumper( \%hash ); use Data::Dumper; foreach my $field ( $self->_required ) { next if exists $hash{$field}; carp "Missing field [$field] for track()"; return; } my $tracking_number = $self->is_valid_tracking_number( $hash{'TrackID'} ); unless( $tracking_number ) { carp "String [$hash{'TrackID'}] does not look like a valid USPS tracking number"; return; } $self->_make_url( \%hash ); $self->_make_request; $self->_parse_response; } =item tracking_number_regex Returns the regex that checks a tracking number. I have it in its own method so you can easily override it if I got it wrong. The USPS shows the valid forms at https://tools.usps.com/go/TrackConfirmAction!input.action USPS Tracking® 9400 1000 0000 0000 0000 00 Priority Mail® 9205 5000 0000 0000 0000 00 Certified Mail® 9407 3000 0000 0000 0000 00 Collect on Delivery 9303 3000 0000 0000 0000 00 Global Express Guaranteed® 82 000 000 00 Priority Mail Express International™ EC 000 000 000 US Priority Mail Express™ 9270 1000 0000 0000 0000 00 EA 000 000 000 US Priority Mail International® CP 000 000 000 US Registered Mail™ 9208 8000 0000 0000 0000 00 Signature Confirmation™ 9202 1000 0000 0000 0000 00 =cut sub tracking_number_regex { state $regex = qr/ \A 9 [234] [0-9]{20} | 82 [0-9]{8} | [A-Z]{2}[0-9]{9}US \z /x; return $regex; } =item is_valid_tracking_number( ID ) Returns a normalized version of the tracking number if ID looks like a tracking number, based on the regex from C. Returns false otherwise. Normalizing ID merely removes all whitespace. Sometimes the USPS shows the numbers with whitespace. =cut sub is_valid_tracking_number { my( $self, $tracking_number ) = @_; $tracking_number =~ s/\s+//g; return unless $tracking_number =~ $self->tracking_number_regex; $tracking_number; } =item service_type( ID ) Returns the service type, based on the examples shown by the USPS and shown in C. I know this is wrong because I have tracking numbers that don't have the same leading characters for Priority Mail International. =cut sub service_type { my( $self, $tracking_number ); return unless $tracking_number =~ $self->tracking_number_regex; return do { local $_ = $tracking_number; if( / \A 94 /x ) { 'USPS Tracking' } elsif( / \A 9205 /x ) { 'Priority Mail' } elsif( / \A 9407 /x ) { 'Certified Mail' } elsif( / \A 9303 /x ) { 'Collect on Delivery' } elsif( / \A 82 /x ) { 'Global Express Guaranteed' } elsif( / \A 9270 /x ) { 'Priority Mail Express' } elsif( / \A 9208 /x ) { 'Registered Mail' } elsif( / \A 9202 /x ) { 'Signature Confirmation' } elsif( / \A RA .* US \z /x ) { 'Registered Mail' } elsif( / \A EA .* US \z /x ) { 'Priority Mail Express' } elsif( / \A EC .* US \z /x ) { 'Priority Mail Express International' } elsif( / \A CP .* US \z /x ) { 'Priority Mail International' } else { 'Unknown' } }; } sub _api_name { "TrackV2" } sub _make_query_xml { my( $self, $hash ) = @_; my $user = $self->userid; my $pass = $self->password; my $id = $hash->{'TrackID'}; my $ip = $hash->{'ClientIp'} // '127.0.0.1'; my $source = $hash->{'SourceId'} // __PACKAGE__; my $xml = qq|| . qq|1| . qq|| . qq|| . qq||; foreach my $field ( $self->_fields ) { next if $field eq 'TrackID'; next unless defined $hash->{$field}; $xml .= "<$field>$$hash{$field}"; } $xml .= qq||; say "XML is\n$xml\n"; return $xml; } sub _parse_response { my( $self ) = @_; my $response = $self->response; my( $summary ) = $response =~ m{(.*?)}s; my @details = $response =~ m{(.*?)}s; my %hash = (); $hash{'TrackSummary'} = $summary; $hash{'TrackDetail'} = [ map { $self->_parse_subbits( $_ ) } @details ]; bless \%hash, ref $self; # 'Hash::AsObject'; } sub _parse_subbits { state $fields = [ qw( EventTime EventDate Event EventCity EventState EventZIPCode EventCountry FirmName Name AuthorizedAgent ) ]; my( $self, $subbit ) = @_; my %hash; foreach my $field ( @$fields ) { my( $value ) = $subbit =~ m|<$field>(.*?)|sg; $hash{$field} = $value || ''; } return \%hash; } =back =head1 TO DO =head1 SEE ALSO L The WebTools API is documented on the US Postal Service's website: https://www.usps.com/business/web-tools-apis/track-and-confirm-api.htm =head1 SOURCE AVAILABILITY This source is in GitHub: https://github.com/briandfoy/business-us-usps-webtools =head1 AUTHOR brian d foy, C<< >> =head1 COPYRIGHT AND LICENSE Copyright © 2006-2016, brian d foy . All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; business-us-usps-webtools-release-1.122/lib/Business/US/USPS/WebTools/ZipCodeLookup.pm000066400000000000000000000062771277755100700305750ustar00rootroot00000000000000use v5.10; use utf8; package Business::US::USPS::WebTools::ZipCodeLookup; use strict; no warnings 'uninitialized'; use parent qw(Business::US::USPS::WebTools); use subs qw(); use vars qw($VERSION); $VERSION = '1.122'; =encoding utf8 =head1 NAME Business::US::USPS::WebTools::ZipCodeLookup - lookup a Zip Code using the USPS Web Tools =head1 SYNOPSIS use Business::US::USPS::WebTools::ZipCodeLookup; my $looker_upper = Business::US::USPS::WebTools::ZipCodeLookup->new( { UserID => $ENV{USPS_WEBTOOLS_USERID}, Password => $ENV{USPS_WEBTOOLS_PASSWORD}, Testing => 1, } ); my $hash = $looker_upper->lookup_zipcode( ); if( $looker_upper->is_error ) { warn "Oh No! $looker_upper->{error}{description}\n"; } else { print join "\n", map { "$_: $hash->{$_}" } qw(FirmName Address1 Address2 City State Zip5 Zip4); } =head1 DESCRIPTION *** THIS IS ALPHA SOFTWARE *** This module implements the Zip Code Lookup web service from the US Postal Service. It is a subclass of Business::US::USPS::WebTools. =cut =over 4 =cut sub _fields { qw( FirmName Address1 Address2 City State) } sub _required { qw( Address2 City State ) } =item lookup_zipcode( KEY, VALUE, ... ) The C method takes the following keys, which come directly from the USPS web service interface: Address2 The street address City The name of the city State The two letter state abbreviation Zip5 The 5 digit zip code Zip4 The 4 digit extension to the zip code It returns an anonymous hash with the same keys, but the values are the USPS's canonicalized address. If there is an error, the hash values will be the empty string, and the error flag is set. Check is with C: $verifier->is_error; See the C documentation in Business::US::USPS::WebTools for more details on error information. =cut sub lookup_zipcode { my( $self, %hash ) = @_; $self->_make_url( \%hash ); $self->_make_request; $self->_parse_response; } sub _api_name { "ZipCodeLookup" } sub _make_query_xml { my( $self, $hash ) = @_; my $user = $self->userid; my $pass = $self->password; my $xml = qq|| . qq|
|; foreach my $field ( $self->_fields ) { $xml .= "<$field>$$hash{$field}"; } $xml .= qq|
|; return $xml; } sub _parse_response { my( $self ) = @_; #require 'Hash::AsObject'; my %hash = (); foreach my $field ( $self->_fields, qw( Zip5 Zip4 ) ) { my( $value ) = $self->response =~ m|<$field>(.*?)|g; $hash{$field} = $value || ''; } bless \%hash, ref $self; # 'Hash::AsObject'; } =back =head1 TO DO =head1 SEE ALSO L The WebTools API is documented on the US Postal Service's website: http://www.usps.com/webtools/htm/Address-Information.htm =head1 SOURCE AVAILABILITY This source is in GitHub: https://github.com/briandfoy/business-us-usps-webtools =head1 AUTHOR brian d foy, C<< >> =head1 COPYRIGHT AND LICENSE Copyright © 2006-2016, brian d foy . All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; business-us-usps-webtools-release-1.122/t/000077500000000000000000000000001277755100700205175ustar00rootroot00000000000000business-us-usps-webtools-release-1.122/t/address_verification.t000066400000000000000000000452551277755100700251060ustar00rootroot00000000000000#!/usr/bin/perl # See http://www.usps.com/webtools/htm/Address-Information.htm for # the test requirements. The headings ( "Good response #1", etc ) # correspond to the USPS test specification # # the sample requests are now at https://www.usps.com/business/web-tools-apis/general-api-developer-guide.htm#_Toc423593927 # but I haven't updated this. Some requests no longer appear there but # they still work. use Test::More; my $class = "Business::US::USPS::WebTools::AddressStandardization"; my $method = 'verify_address'; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # unless( $ENV{USPS_WEBTOOLS_USERID} and $ENV{USPS_WEBTOOLS_PASSWORD} ) { plan skip_all => "You must set the USPS_WEBTOOLS_USERID and USPS_WEBTOOLS_PASSWORD " . "environment variables to run these tests\n"; } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # use_ok( $class ); my $verifier; my $base = qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=Verify&XML=%3CAddressValidateRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CIncludeOptionalElements%3Etrue%3C%2FIncludeOptionalElements%3E%3CReturnCarrierRoute%3Etrue%3C%2FReturnCarrierRoute%3E|; subtest setup => sub { $verifier = $class->new( { UserID => $ENV{USPS_WEBTOOLS_USERID}, Password => $ENV{USPS_WEBTOOLS_PASSWORD}, Testing => 1, } ); isa_ok( $verifier, $class ); can_ok( $verifier, $method ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Good response #1 subtest good_response_1 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '6406 Ivy Lane', City => 'Greenbelt', State => 'MD', Zip5 => '', Zip4 => '', } ); is( $url, qq|$base%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E6406+Ivy+Lane%3C%2FAddress2%3E%3CCity%3EGreenbelt%3C%2FCity%3E%3CState%3EMD%3C%2FState%3E%3CZip5%3E%3C%2FZip5%3E%3CZip4%3E%3C%2FZip4%3E%3C%2FAddress%3E%3C%2FAddressValidateRequest%3E|, "URL for Ivy Lane is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( ! $verifier->is_error, "Response is not an error" ); my $expected = <<"XML";
6406 IVY LNGREENBELTMD20770144106C023
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); my $hash = $verifier->_parse_response; is( $hash->{FirmName}, '', 'FirmName matches for Ivy Lane' ); is( $hash->{Address1}, '', 'Address1 matches for Ivy Lane' ); is( $hash->{Address2}, '6406 IVY LN', 'Address2 matches for Ivy Lane' ); is( $hash->{City}, 'GREENBELT', 'City matches for Ivy Lane' ); is( $hash->{State}, 'MD', 'State matches for Ivy Lane' ); is( $hash->{Zip5}, '20770', 'Zip5 matches for Ivy Lane' ); is( $hash->{Zip4}, '1441', 'Zip4 matches for Ivy Lane' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Good response #2 subtest good_response_1 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '8 Wildwood Drive', City => 'Old Lyme', State => 'CT', Zip5 => '06371', Zip4 => '', } ); is( $url, qq|$base%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E8+Wildwood+Drive%3C%2FAddress2%3E%3CCity%3EOld+Lyme%3C%2FCity%3E%3CState%3ECT%3C%2FState%3E%3CZip5%3E06371%3C%2FZip5%3E%3CZip4%3E%3C%2FZip4%3E%3C%2FAddress%3E%3C%2FAddressValidateRequest%3E|, "URL for Wildwood Drive is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( ! $verifier->is_error, "Response is not an error" ); my $expected = <<"XML";
8 WILDWOOD DROLD LYMECT06371184408R010
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); my $hash = $verifier->_parse_response; is( $hash->{FirmName}, '', 'FirmName matches for Wildwood' ); is( $hash->{Address1}, '', 'Address1 matches for Wildwood' ); is( $hash->{Address2}, '8 WILDWOOD DR', 'Address2 matches for Wildwood' ); is( $hash->{City}, 'OLD LYME', 'City matches for Wildwood' ); is( $hash->{State}, 'CT', 'State matches for Wildwood' ); is( $hash->{Zip5}, '06371', 'Zip5 matches for Wildwood' ); is( $hash->{Zip4}, '1844', 'Zip4 matches for Wildwood' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Good response #3 subtest good_response_3 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '4411 Romlon Street', City => 'Beltsville', State => 'MD', Zip5 => '', Zip4 => '', } ); is( $url, qq|$base%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E4411+Romlon+Street%3C%2FAddress2%3E%3CCity%3EBeltsville%3C%2FCity%3E%3CState%3EMD%3C%2FState%3E%3CZip5%3E%3C%2FZip5%3E%3CZip4%3E%3C%2FZip4%3E%3C%2FAddress%3E%3C%2FAddressValidateRequest%3E|, "URL for Romlan Street is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( ! $verifier->is_error, "Response is not an error" ); my $expected = <<"XML";
4411 ROMLON STBELTSVILLEMD207052425Default address: The address you entered was found but more information is needed (such as an apartment, suite, or box number) to match to a specific address.C017
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); my $hash = $verifier->_parse_response; is( $hash->{FirmName}, '', 'FirmName matches for Romlan' ); is( $hash->{Address1}, '', 'Address1 matches for Romlan' ); is( $hash->{Address2}, '4411 ROMLON ST', 'Address2 matches for Romlan' ); is( $hash->{City}, 'BELTSVILLE', 'City matches for Romlan' ); is( $hash->{State}, 'MD', 'State matches for Romlan' ); is( $hash->{Zip5}, '20705', 'Zip5 matches for Romlan' ); is( $hash->{Zip4}, '2425', 'Zip4 matches for Romlan' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Good response #4 subtest good_response_4 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '3527 Sharonwood Road Apt. 3C', City => 'Laurel', State => 'MD', Zip5 => '', Zip4 => '', } ); is( $url, qq|$base%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E3527+Sharonwood+Road+Apt.+3C%3C%2FAddress2%3E%3CCity%3ELaurel%3C%2FCity%3E%3CState%3EMD%3C%2FState%3E%3CZip5%3E%3C%2FZip5%3E%3CZip4%3E%3C%2FZip4%3E%3C%2FAddress%3E%3C%2FAddressValidateRequest%3E|, "URL for Sharonwood Road is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( ! $verifier->is_error, "Response is not an error" ); my $expected = <<"XML";
3527 SHARONWOOD RD APT 3CLAURELMD20724592033R008
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); my $hash = $verifier->_parse_response; is( $hash->{FirmName}, '', 'FirmName matches for Sharonwood' ); is( $hash->{Address1}, '', 'Address1 matches for Sharonwood' ); is( $hash->{Address2}, '3527 SHARONWOOD RD APT 3C', 'Address2 matches for Sharonwood' ); is( $hash->{City}, 'LAUREL', 'City matches for Sharonwood' ); is( $hash->{State}, 'MD', 'State matches for Sharonwood' ); is( $hash->{Zip5}, '20724', 'Zip5 matches for Sharonwood' ); is( $hash->{Zip4}, '5920', 'Zip4 matches for Sharonwood' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Error Requests # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Error response #1 subtest error_response_1 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '3527 Sharonwood Road Apt. 3C', City => 'Wilmington', State => 'DE', Zip5 => '', Zip4 => '', } ); is( $url, qq|$base%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E3527+Sharonwood+Road+Apt.+3C%3C%2FAddress2%3E%3CCity%3EWilmington%3C%2FCity%3E%3CState%3EDE%3C%2FState%3E%3CZip5%3E%3C%2FZip5%3E%3CZip4%3E%3C%2FZip4%3E%3C%2FAddress%3E%3C%2FAddressValidateRequest%3E|, "URL for Sharonwood Road Error is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( $verifier->is_error, "Error request gets an error response" ); my $expected = <<"XML";
-2147219401clsAMSAddress Not Found.
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); is( $verifier->{error}{number}, -2147219401, 'Error number matches for Sharonwood error' ); is( $verifier->{error}{source}, 'clsAMS', 'Error source matches for Sharonwood error' ); is( $verifier->{error}{description}, 'Address Not Found. ', 'Error description matches for Sharonwood error' ); is( $verifier->{error}{help_file}, undef, 'Error help file matches for Sharonwood error' ); is( $verifier->{error}{help_context}, undef, 'Error help context matches for Sharonwood error' ); my $hash = $verifier->_parse_response; is( $hash->{FirmName}, '', 'FirmName is empty for Sharonwood error' ); is( $hash->{Address1}, '', 'Address1 is empty for Sharonwood error' ); is( $hash->{Address2}, '', 'Address2 is empty for Sharonwood error' ); is( $hash->{City}, '', 'City is empty for Sharonwood error' ); is( $hash->{State}, '', 'State is empty for Sharonwood error' ); is( $hash->{Zip5}, '', 'Zip5 is empty for Sharonwood error' ); is( $hash->{Zip4}, '', 'Zip4 is empty for Sharonwood error' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Error response #2 =pod # this works now { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '1600 Pennsylvania Avenue', City => 'Washington', State => 'DC', Zip5 => '', Zip4 => '', } ); is( $url, qq|$base%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E1600+Pennsylvania+Avenue%3C%2FAddress2%3E%3CCity%3EWashington%3C%2FCity%3E%3CState%3EDC%3C%2FState%3E%3CZip5%3E%3C%2FZip5%3E%3CZip4%3E%3C%2FZip4%3E%3C%2FAddress%3E%3C%2FAddressValidateRequest%3E|, "URL for Pennsylvania Avenue Error is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( $verifier->is_error, "Error request gets an error response" ); my $expected = <<"XML";
-2147219403SOLServerTest;SOLServerTest.CallAddressDllMultiple responses found. No default address.
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); is( $verifier->{error}{number}, -2147219403, 'Error number matches for Pennsylvania Avenue error' ); is( $verifier->{error}{source}, 'clsAMS', 'Error source matches for Pennsylvania Avenue error' ); is( $verifier->{error}{description}, 'Multiple responses found. No default address.', 'Error description matches for Pennsylvania Avenue error' ); is( $verifier->{error}{help_file}, undef, 'Error help file matches for Pennsylvania Avenue error' ); is( $verifier->{error}{help_context}, undef, 'Error help context matches for Pennsylvania Avenue error' ); my $hash = $verifier->_parse_response; # print STDERR "In _make_request:\n" . Dumper( $verifier ) . "\n"; is( $hash->{FirmName}, '', 'FirmName is empty for Pennsylvania Avenue error' ); is( $hash->{Address1}, '', 'Address1 is empty for Pennsylvania Avenue error' ); is( $hash->{Address2}, '', 'Address2 is empty for Pennsylvania Avenue error' ); is( $hash->{City}, '', 'City is empty for Pennsylvania Avenue error' ); is( $hash->{State}, '', 'State is empty for Pennsylvania Avenue error' ); is( $hash->{Zip5}, '', 'Zip5 is empty for Pennsylvania Avenue error' ); is( $hash->{Zip4}, '', 'Zip4 is empty for Pennsylvania Avenue error' ); }; =cut # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Error response #3 subtest error_response_3 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '123 Main Street', City => 'Washington', State => 'ZZ', Zip5 => '', Zip4 => '', } ); is( $url, qq|$base%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E123+Main+Street%3C%2FAddress2%3E%3CCity%3EWashington%3C%2FCity%3E%3CState%3EZZ%3C%2FState%3E%3CZip5%3E%3C%2FZip5%3E%3CZip4%3E%3C%2FZip4%3E%3C%2FAddress%3E%3C%2FAddressValidateRequest%3E|, "URL for Main Street Error is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( $verifier->is_error, "Error request gets an error response" ); my $expected = <<"XML";
-2147219402clsAMSInvalid State Code.
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); is( $verifier->{error}{number}, -2147219402, 'Error number matches for Main Street error' ); is( $verifier->{error}{source}, 'clsAMS', 'Error source matches for Main Street error' ); is( $verifier->{error}{description}, 'Invalid State Code. ', 'Error description matches for Main Street error' ); is( $verifier->{error}{help_file}, undef, 'Error help file matches for Main Street error' ); is( $verifier->{error}{help_context}, undef, 'Error help context matches for Main Street error' ); my $hash = $verifier->_parse_response; # print STDERR "In _make_request:\n" . Dumper( $verifier ) . "\n"; is( $hash->{FirmName}, '', 'FirmName is empty for Main Street error' ); is( $hash->{Address1}, '', 'Address1 is empty for Main Street error' ); is( $hash->{Address2}, '', 'Address2 is empty for Main Street error' ); is( $hash->{City}, '', 'City is empty for Main Street error' ); is( $hash->{State}, '', 'State is empty for Main Street error' ); is( $hash->{Zip5}, '', 'Zip5 is empty for Main Street error' ); is( $hash->{Zip4}, '', 'Zip4 is empty for Main Street error' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Error response #4 subtest error_response_4 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '123 Main Street', City => 'Trenton', State => 'NJ', Zip5 => '', Zip4 => '', } ); is( $url, qq|$base%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E123+Main+Street%3C%2FAddress2%3E%3CCity%3ETrenton%3C%2FCity%3E%3CState%3ENJ%3C%2FState%3E%3CZip5%3E%3C%2FZip5%3E%3CZip4%3E%3C%2FZip4%3E%3C%2FAddress%3E%3C%2FAddressValidateRequest%3E|, "URL for Trenton, NJ Error is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( $verifier->is_error, "Error request gets an error response" ); my $expected = <<"XML";
-2147219401clsAMSAddress Not Found.
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); is( $verifier->{error}{number}, -2147219401, 'Error number matches for Trenton, NJ error' ); is( $verifier->{error}{source}, 'clsAMS', 'Error source matches for Trenton, NJ error' ); is( $verifier->{error}{description}, 'Address Not Found. ', 'Error description matches for Trenton, NJ error' ); is( $verifier->{error}{help_file}, undef, 'Error help file matches for Trenton, NJ error' ); is( $verifier->{error}{help_context}, undef, 'Error help context matches for Trenton, NJ error' ); my $hash = $verifier->_parse_response; # print STDERR "In _make_request:\n" . Dumper( $verifier ) . "\n"; is( $hash->{FirmName}, '', 'FirmName is empty for Trenton, NJ error' ); is( $hash->{Address1}, '', 'Address1 is empty for Trenton, NJ error' ); is( $hash->{Address2}, '', 'Address2 is empty for Trenton, NJ error' ); is( $hash->{City}, '', 'City is empty for Trenton, NJ error' ); is( $hash->{State}, '', 'State is empty for Trenton, NJ error' ); is( $hash->{Zip5}, '', 'Zip5 is empty for Trenton, NJ error' ); is( $hash->{Zip4}, '', 'Zip4 is empty for Trenton, NJ error' ); }; done_testing(); business-us-usps-webtools-release-1.122/t/city_state_lookup.t000066400000000000000000000224301277755100700244460ustar00rootroot00000000000000#!/usr/bin/perl # See http://www.usps.com/webtools/htm/Address-Information.htm for # the test requirements. The headings ( "Good response #1", etc ) # correspond to the USPS test specification # # the sample requests are now at https://www.usps.com/business/web-tools-apis/general-api-developer-guide.htm#_Toc423593927 # but I haven't updated this. Some requests no longer appear there but # they still work. use Test::More 0.98; my $class = "Business::US::USPS::WebTools::CityStateLookup"; my $method = 'lookup_city_state'; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # unless( $ENV{USPS_WEBTOOLS_USERID} and $ENV{USPS_WEBTOOLS_PASSWORD} ) { plan skip_all => "You must set the USPS_WEBTOOLS_USERID and USPS_WEBTOOLS_PASSWORD " . "environment variables to run these tests\n"; } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # use_ok( $class ); my $verifier; subtest setup => sub { $verifier = $class->new( { UserID => $ENV{USPS_WEBTOOLS_USERID}, Password => $ENV{USPS_WEBTOOLS_PASSWORD}, Testing => 1, } ); isa_ok( $verifier, $class ); can_ok( $verifier, $method ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Good response #1 subtest good_response_1 => sub { my $url = $verifier->_make_url( { Zip5 => 90210, } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=CityStateLookup&XML=%3CCityStateLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CZipCode+ID%3D%220%22%3E%3CZip5%3E90210%3C%2FZip5%3E%3C%2FZipCode%3E%3C%2FCityStateLookupRequest%3E|, "URL for 90210 is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( ! $verifier->is_error, "90210 response is not an error" ); my $expected = <<"XML"; 90210BEVERLY HILLSCA XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); my $hash = $verifier->_parse_response; is( $hash->{City}, 'BEVERLY HILLS', 'City matches for 90210' ); is( $hash->{State}, 'CA', 'State matches for 90210' ); is( $hash->{Zip5}, '90210', 'Zip5 matches for 90210' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Good response #2 subtest good_response_2 => sub { my $url = $verifier->_make_url( { Zip5 => '20770', } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=CityStateLookup&XML=%3CCityStateLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CZipCode+ID%3D%220%22%3E%3CZip5%3E20770%3C%2FZip5%3E%3C%2FZipCode%3E%3C%2FCityStateLookupRequest%3E|, "URL for 20770 is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( ! $verifier->is_error, "20770 response is not an error" ); my $expected = <<"XML"; 20770GREENBELTMD XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); my $hash = $verifier->_parse_response; is( $hash->{City}, 'GREENBELT', 'City matches for 20770' ); is( $hash->{State}, 'MD', 'State matches for 20770' ); is( $hash->{Zip5}, '20770', 'Zip5 matches for 20770' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Good response #3 subtest good_response_3 => sub { my $url = $verifier->_make_url( { Zip5 => '21113', } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=CityStateLookup&XML=%3CCityStateLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CZipCode+ID%3D%220%22%3E%3CZip5%3E21113%3C%2FZip5%3E%3C%2FZipCode%3E%3C%2FCityStateLookupRequest%3E|, "URL for 21113 is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( ! $verifier->is_error, "Response is not an error" ); my $expected = <<"XML"; 21113ODENTONMD XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); my $hash = $verifier->_parse_response; is( $hash->{City}, 'ODENTON', 'City matches for 21113' ); is( $hash->{State}, 'MD', 'State matches for 21113' ); is( $hash->{Zip5}, '21113', 'Zip5 matches for 21113' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Good response #4 subtest good_response_4 => sub { my $url = $verifier->_make_url( { Zip5 => '21032', } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=CityStateLookup&XML=%3CCityStateLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CZipCode+ID%3D%220%22%3E%3CZip5%3E21032%3C%2FZip5%3E%3C%2FZipCode%3E%3C%2FCityStateLookupRequest%3E|, "URL for 21032 is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( ! $verifier->is_error, "21032 response is not an error" ); my $expected = <<"XML"; 21032CROWNSVILLEMD XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); my $hash = $verifier->_parse_response; is( $hash->{City}, 'CROWNSVILLE', 'City matches for 21032' ); is( $hash->{State}, 'MD', 'State matches for 21032' ); is( $hash->{Zip5}, '21032', 'Zip5 matches for 21032' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Good response #5 =pod # this no longer works subtest good_response_5 => sub { my $url = $verifier->_make_url( { Zip5 => '21117', } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=CityStateLookup&XML=%3CCityStateLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CZipCode+ID%3D%220%22%3E%3CZip5%3E21117%3C%2FZip5%3E%3C%2FZipCode%3E%3C%2FCityStateLookupRequest%3E|, "URL for Sharonwood Road is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( ! $verifier->is_error, "21117 response is not an error" ); my $expected = <<"XML"; -2147219399WebtoolsAMS;CityStateLookupInvalid Zip Code. XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); my $hash = $verifier->_parse_response; is( $hash->{City}, 'OWINGS MILLS', 'City matches for 21117' ); is( $hash->{State}, 'MD', 'State matches for 21117' ); is( $hash->{Zip5}, '21117', 'Zip5 matches for 21117' ); }; =cut # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Error Requests # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Error response #1 subtest error_response_1 => sub { my $url = $verifier->_make_url( { Zip5 => '99999', } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=CityStateLookup&XML=%3CCityStateLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CZipCode+ID%3D%220%22%3E%3CZip5%3E99999%3C%2FZip5%3E%3C%2FZipCode%3E%3C%2FCityStateLookupRequest%3E|, "URL for Sharonwood Road Error is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( $verifier->is_error, "Error request gets an error response" ); my $expected = <<"XML"; -2147219399WebtoolsAMS;CityStateLookupInvalid Zip Code. XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); is( $verifier->{error}{number}, -2147219399, 'Error number matches for 99999 error' ); is( $verifier->{error}{source}, 'WebtoolsAMS;CityStateLookup', 'Error source matches for 99999 error' ); is( $verifier->{error}{description}, 'Invalid Zip Code.', 'Error description matches for 99999 error' ); is( $verifier->{error}{help_file}, undef, 'Error help file matches for 99999 error' ); is( $verifier->{error}{help_context}, undef, 'Error help context matches for 99999 error' ); my $hash = $verifier->_parse_response; is( $hash->{City}, '', 'City is empty for Sharonwood error' ); is( $hash->{State}, '', 'State is empty for Sharonwood error' ); is( $hash->{Zip5}, '', 'Zip5 is empty for Sharonwood error' ); }; done_testing(); business-us-usps-webtools-release-1.122/t/load.t000066400000000000000000000005101277755100700216170ustar00rootroot00000000000000BEGIN { @classes = qw( Business::US::USPS::WebTools Business::US::USPS::WebTools::AddressStandardization Business::US::USPS::WebTools::ZipCodeLookup Business::US::USPS::WebTools::CityStateLookup ); } use Test::More tests => scalar @classes; foreach my $class ( @classes ) { BAIL_OUT() unless use_ok( $class ); } business-us-usps-webtools-release-1.122/t/pod.t000066400000000000000000000002011277755100700214570ustar00rootroot00000000000000use Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok(); business-us-usps-webtools-release-1.122/t/pod_coverage.t000066400000000000000000000002611277755100700233400ustar00rootroot00000000000000#!/usr/bin/perl use Test::More; eval "use Test::Pod::Coverage 1.00"; plan skip_all => "Test::Pod::Coverage 1.00 required for testing POD coverage" if $@; all_pod_coverage_ok(); business-us-usps-webtools-release-1.122/t/test_manifest000066400000000000000000000001711277755100700233060ustar00rootroot00000000000000#env.t load.t pod.t pod_coverage.t test_or_live.t #prereq.t address_verification.t zip_code_lookup.t city_state_lookup.t business-us-usps-webtools-release-1.122/t/test_or_live.t000066400000000000000000000030221277755100700233770ustar00rootroot00000000000000use Test::More 0.98; my $class = "Business::US::USPS::WebTools"; use_ok( $class ); # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # subtest testing => sub { my $webtools = $class->new( { UserID => 'fake_user', Password => "this won't work", Testing => 1, } ); ok( $webtools->_testing, "I think I'm testing" ); is( ! $webtools->_live, 1, "I don't think I'm live!" ); is( $webtools->_api_host, "testing.shippingapis.com", "Testing host is right" ); is( $webtools->_api_path, "/ShippingAPITest.dll", "Testing path is right" ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # subtest not_testing => sub { my $webtools = $class->new( { UserID => 'fake_user', Password => "this won't work", Testing => 0, } ); ok( $webtools->_live, "I think I'm live" ); is( ! $webtools->_testing, 1, "I don't think I'm testing!" ); is( $webtools->_api_host, "production.shippingapis.com", "Live host is right" ); is( $webtools->_api_path, "/ShippingAPI.dll", "Testing path is right" ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Passing empty hash subtest empty => sub { my $webtools = $class->new( { UserID => 'fake_user', Password => "this won't work", } ); ok( $webtools->_live, "I think I'm live" ); is( ! $webtools->_testing, 1, "I don't think I'm testing!" ); is( $webtools->_api_host, "production.shippingapis.com", "Live host is right" ); is( $webtools->_api_path, "/ShippingAPI.dll", "Testing path is right" ); }; done_testing(); business-us-usps-webtools-release-1.122/t/track_confirm.t000066400000000000000000000003521277755100700235250ustar00rootroot00000000000000#!/usr/bin/perl use Test::More; my $class = "Business::US::USPS::WebTools::TrackConfirm"; my $method = 'track'; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # use_ok( $class ); done_testing(); business-us-usps-webtools-release-1.122/t/zip_code_lookup.t000066400000000000000000000456601277755100700241040ustar00rootroot00000000000000#!/usr/bin/perl # See http://www.usps.com/webtools/htm/Address-Information.htm for # the test requirements. The headings ( "Good response #1", etc ) # correspond to the USPS test specification # # the sample requests are now at https://www.usps.com/business/web-tools-apis/general-api-developer-guide.htm#_Toc423593927 # but I haven't updated this. Some requests no longer appear there but # they still work. use Test::More 0.98; my $class = "Business::US::USPS::WebTools::ZipCodeLookup"; my $method = 'lookup_zipcode'; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # unless( $ENV{USPS_WEBTOOLS_USERID} and $ENV{USPS_WEBTOOLS_PASSWORD} ) { plan skip_all => "You must set the USPS_WEBTOOLS_USERID and USPS_WEBTOOLS_PASSWORD " . "environment variables to run these tests\n"; } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # my $verifier; subtest setup => sub { use_ok( $class ); $verifier = $class->new( { UserID => $ENV{USPS_WEBTOOLS_USERID}, Password => $ENV{USPS_WEBTOOLS_PASSWORD}, Testing => 1, } ); isa_ok( $verifier, $class ); can_ok( $verifier, $method ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Good Request #1 subtest good_request_1 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '6406 Ivy Lane', City => 'Greenbelt', State => 'MD', Zip5 => '', Zip4 => '', } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=ZipCodeLookup&XML=%3CZipCodeLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E6406+Ivy+Lane%3C%2FAddress2%3E%3CCity%3EGreenbelt%3C%2FCity%3E%3CState%3EMD%3C%2FState%3E%3C%2FAddress%3E%3C%2FZipCodeLookupRequest%3E|, "URL for Ivy Lane is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( ! $verifier->is_error, "Response is not an error" ); my $expected = <<"XML";
6406 IVY LNGREENBELTMD207701441
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); my $hash = $verifier->_parse_response; is( $hash->{Address2}, '6406 IVY LN', 'Address2 matches for Ivy Lane' ); is( $hash->{City}, 'GREENBELT', 'City matches for Ivy Lane' ); is( $hash->{State}, 'MD', 'State matches for Ivy Lane' ); is( $hash->{Zip5}, '20770', 'Zip5 matches for Ivy Lane' ); is( $hash->{Zip4}, '1441', 'Zip4 matches for Ivy Lane' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Good request 2 subtest good_request_2 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '8 Wildwood Drive', City => 'Old Lyme', State => 'CT', Zip5 => '06371', Zip4 => '', } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=ZipCodeLookup&XML=%3CZipCodeLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E8+Wildwood+Drive%3C%2FAddress2%3E%3CCity%3EOld+Lyme%3C%2FCity%3E%3CState%3ECT%3C%2FState%3E%3C%2FAddress%3E%3C%2FZipCodeLookupRequest%3E|, "URL for Wildwood Drive is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( ! $verifier->is_error, "Response is not an error" ); my $expected = <<"XML";
8 WILDWOOD DROLD LYMECT063711844
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); my $hash = $verifier->_parse_response; is( $hash->{FirmName}, '', 'FirmName matches for Wildwood' ); is( $hash->{Address1}, '', 'Address1 matches for Wildwood' ); is( $hash->{Address2}, '8 WILDWOOD DR', 'Address2 matches for Wildwood' ); is( $hash->{City}, 'OLD LYME', 'City matches for Wildwood' ); is( $hash->{State}, 'CT', 'State matches for Wildwood' ); is( $hash->{Zip5}, '06371', 'Zip5 matches for Wildwood' ); is( $hash->{Zip4}, '1844', 'Zip4 matches for Wildwood' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Good request 3 subtest good_request_3 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '4411 Romlon Street', City => 'Beltsville', State => 'MD', Zip5 => '', Zip4 => '', } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=ZipCodeLookup&XML=%3CZipCodeLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E4411+Romlon+Street%3C%2FAddress2%3E%3CCity%3EBeltsville%3C%2FCity%3E%3CState%3EMD%3C%2FState%3E%3C%2FAddress%3E%3C%2FZipCodeLookupRequest%3E|, "URL for Romlan Street is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( ! $verifier->is_error, "Response is not an error" ); my $expected = <<"XML";
4411 ROMLON STBELTSVILLEMD207052425Default address: The address you entered was found but more information is needed (such as an apartment, suite, or box number) to match to a specific address.
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); my $hash = $verifier->_parse_response; is( $hash->{FirmName}, '', 'FirmName matches for Romlan' ); is( $hash->{Address1}, '', 'Address1 matches for Romlan' ); is( $hash->{Address2}, '4411 ROMLON ST', 'Address2 matches for Romlan' ); is( $hash->{City}, 'BELTSVILLE', 'City matches for Romlan' ); is( $hash->{State}, 'MD', 'State matches for Romlan' ); is( $hash->{Zip5}, '20705', 'Zip5 matches for Romlan' ); is( $hash->{Zip4}, '2425', 'Zip4 matches for Romlan' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Good request 4 subtest good_request_4 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '3527 Sharonwood Road Apt. 3C', City => 'Laurel', State => 'MD', Zip5 => '', Zip4 => '', } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=ZipCodeLookup&XML=%3CZipCodeLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E3527+Sharonwood+Road+Apt.+3C%3C%2FAddress2%3E%3CCity%3ELaurel%3C%2FCity%3E%3CState%3EMD%3C%2FState%3E%3C%2FAddress%3E%3C%2FZipCodeLookupRequest%3E|, "URL for Sharonwood Road is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( ! $verifier->is_error, "Response is not an error" ); my $expected = <<"XML";
3527 SHARONWOOD RD APT 3CLAURELMD207245920
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); my $hash = $verifier->_parse_response; is( $hash->{FirmName}, '', 'FirmName matches for Sharonwood' ); is( $hash->{Address1}, '', 'Address1 matches for Sharonwood' ); is( $hash->{Address2}, '3527 SHARONWOOD RD APT 3C', 'Address2 matches for Sharonwood' ); is( $hash->{City}, 'LAUREL', 'City matches for Sharonwood' ); is( $hash->{State}, 'MD', 'State matches for Sharonwood' ); is( $hash->{Zip5}, '20724', 'Zip5 matches for Sharonwood' ); is( $hash->{Zip4}, '5920', 'Zip4 matches for Sharonwood' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Error Requests # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Error response #1 subtest error_response_1 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '3527 Sharonwood Road Apt. 3C', City => 'Wilmington', State => 'DE', Zip5 => '', Zip4 => '', } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=ZipCodeLookup&XML=%3CZipCodeLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E3527+Sharonwood+Road+Apt.+3C%3C%2FAddress2%3E%3CCity%3EWilmington%3C%2FCity%3E%3CState%3EDE%3C%2FState%3E%3C%2FAddress%3E%3C%2FZipCodeLookupRequest%3E|, "URL for Sharonwood Road Error is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( $verifier->is_error, "Error request gets an error response" ); my $expected = <<"XML";
-2147219401clsAMSAddress Not Found.
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); is( $verifier->{error}{number}, -2147219401, 'Error number matches for Sharonwood error' ); is( $verifier->{error}{source}, 'clsAMS', 'Error source matches for Sharonwood error' ); is( $verifier->{error}{description}, 'Address Not Found. ', 'Error description matches for Sharonwood error' ); is( $verifier->{error}{help_file}, undef, 'Error help file matches for Sharonwood error' ); is( $verifier->{error}{help_context}, undef, 'Error help context matches for Sharonwood error' ); my $hash = $verifier->_parse_response; is( $hash->{FirmName}, '', 'FirmName is empty for Sharonwood error' ); is( $hash->{Address1}, '', 'Address1 is empty for Sharonwood error' ); is( $hash->{Address2}, '', 'Address2 is empty for Sharonwood error' ); is( $hash->{City}, '', 'City is empty for Sharonwood error' ); is( $hash->{State}, '', 'State is empty for Sharonwood error' ); is( $hash->{Zip5}, '', 'Zip5 is empty for Sharonwood error' ); is( $hash->{Zip4}, '', 'Zip4 is empty for Sharonwood error' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Error response #2 =pod # this one no longer returns an hour subtest error_response_2 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '1600 Pennsylvania Avenue', City => 'Washington', State => 'DC', Zip5 => '', Zip4 => '', } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=ZipCodeLookup&XML=%3CZipCodeLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E1600+Pennsylvania+Avenue%3C%2FAddress2%3E%3CCity%3EWashington%3C%2FCity%3E%3CState%3EDC%3C%2FState%3E%3C%2FAddress%3E%3C%2FZipCodeLookupRequest%3E|, "URL for Pennsylvania Avenue Error is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( $verifier->is_error, "Error request gets an error response" ); my $expected = <<"XML";
-2147219403SOLServerTest;SOLServerTest.CallAddressDllMultiple responses found. No default address.
XML is( $response, $expected ); is( $verifier->{error}{number}, -2147219403, 'Error number matches for Pennsylvania Avenue error' ); is( $verifier->{error}{source}, 'SOLServerTest;SOLServerTest.CallAddressDll', 'Error source matches for Pennsylvania Avenue error' ); is( $verifier->{error}{description}, 'Multiple responses found. No default address.', 'Error description matches for Pennsylvania Avenue error' ); is( $verifier->{error}{help_file}, '', 'Error help file matches for Pennsylvania Avenue error' ); is( $verifier->{error}{help_context}, '', 'Error help context matches for Pennsylvania Avenue error' ); my $hash = $verifier->_parse_response; # print STDERR "In _make_request:\n" . Dumper( $verifier ) . "\n"; is( $hash->{FirmName}, '', 'FirmName is empty for Pennsylvania Avenue error' ); is( $hash->{Address1}, '', 'Address1 is empty for Pennsylvania Avenue error' ); is( $hash->{Address2}, '', 'Address2 is empty for Pennsylvania Avenue error' ); is( $hash->{City}, '', 'City is empty for Pennsylvania Avenue error' ); is( $hash->{State}, '', 'State is empty for Pennsylvania Avenue error' ); is( $hash->{Zip5}, '', 'Zip5 is empty for Pennsylvania Avenue error' ); is( $hash->{Zip4}, '', 'Zip4 is empty for Pennsylvania Avenue error' ); }; =cut # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Error response #3 subtest error_response_3 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '123 Main Street', City => 'Washington', State => 'ZZ', Zip5 => '', Zip4 => '', } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=ZipCodeLookup&XML=%3CZipCodeLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E123+Main+Street%3C%2FAddress2%3E%3CCity%3EWashington%3C%2FCity%3E%3CState%3EZZ%3C%2FState%3E%3C%2FAddress%3E%3C%2FZipCodeLookupRequest%3E|, "URL for Main Street Error is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( $verifier->is_error, "Error request gets an error response" ); my $expected = <<"XML";
-2147219402clsAMSInvalid State Code.
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); is( $verifier->{error}{number}, -2147219402, 'Error number matches for Main Street error' ); is( $verifier->{error}{source}, 'clsAMS', 'Error source matches for Main Street error' ); is( $verifier->{error}{description}, 'Invalid State Code. ', 'Error description matches for Main Street error' ); is( $verifier->{error}{help_file}, undef, 'Error help file matches for Main Street error' ); is( $verifier->{error}{help_context}, undef, 'Error help context matches for Main Street error' ); my $hash = $verifier->_parse_response; # print STDERR "In _make_request:\n" . Dumper( $verifier ) . "\n"; is( $hash->{FirmName}, '', 'FirmName is empty for Main Street error' ); is( $hash->{Address1}, '', 'Address1 is empty for Main Street error' ); is( $hash->{Address2}, '', 'Address2 is empty for Main Street error' ); is( $hash->{City}, '', 'City is empty for Main Street error' ); is( $hash->{State}, '', 'State is empty for Main Street error' ); is( $hash->{Zip5}, '', 'Zip5 is empty for Main Street error' ); is( $hash->{Zip4}, '', 'Zip4 is empty for Main Street error' ); }; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Error response #4 subtest error_response_3 => sub { my $url = $verifier->_make_url( { FirmName => '', Address1 => '', Address2 => '123 Main Street', City => 'Trenton', State => 'NJ', Zip5 => '', Zip4 => '', } ); is( $url, qq|http://testing.shippingapis.com/ShippingAPITest.dll?API=ZipCodeLookup&XML=%3CZipCodeLookupRequest+USERID%3D%22$ENV{USPS_WEBTOOLS_USERID}%22+PASSWORD%3D%22$ENV{USPS_WEBTOOLS_PASSWORD}%22%3E%3CAddress+ID%3D%220%22%3E%3CFirmName%3E%3C%2FFirmName%3E%3CAddress1%3E%3C%2FAddress1%3E%3CAddress2%3E123+Main+Street%3C%2FAddress2%3E%3CCity%3ETrenton%3C%2FCity%3E%3CState%3ENJ%3C%2FState%3E%3C%2FAddress%3E%3C%2FZipCodeLookupRequest%3E|, "URL for Trenton, NJ Error is correct", ); my $response = $verifier->_make_request; ok( defined $response ); ok( $verifier->is_error, "Error request gets an error response" ); my $expected = <<"XML";
-2147219401clsAMSAddress Not Found.
XML $response =~ s/\s+\z//; $expected =~ s/\s+\z//; is( $response, $expected ); is( $verifier->{error}{number}, -2147219401, 'Error number matches for Trenton, NJ error' ); is( $verifier->{error}{source}, 'clsAMS', 'Error source matches for Trenton, NJ error' ); is( $verifier->{error}{description}, 'Address Not Found. ', 'Error description matches for Trenton, NJ error' ); is( $verifier->{error}{help_file}, undef, 'Error help file matches for Trenton, NJ error' ); is( $verifier->{error}{help_context}, undef, 'Error help context matches for Trenton, NJ error' ); my $hash = $verifier->_parse_response; # print STDERR "In _make_request:\n" . Dumper( $verifier ) . "\n"; is( $hash->{FirmName}, '', 'FirmName is empty for Trenton, NJ error' ); is( $hash->{Address1}, '', 'Address1 is empty for Trenton, NJ error' ); is( $hash->{Address2}, '', 'Address2 is empty for Trenton, NJ error' ); is( $hash->{City}, '', 'City is empty for Trenton, NJ error' ); is( $hash->{State}, '', 'State is empty for Trenton, NJ error' ); is( $hash->{Zip5}, '', 'Zip5 is empty for Trenton, NJ error' ); is( $hash->{Zip4}, '', 'Zip4 is empty for Trenton, NJ error' ); }; done_testing(); business-us-usps-webtools-release-1.122/xt/000077500000000000000000000000001277755100700207075ustar00rootroot00000000000000business-us-usps-webtools-release-1.122/xt/changes.t000066400000000000000000000002031277755100700224770ustar00rootroot00000000000000use Test::More; eval 'use Test::CPAN::Changes'; plan skip_all => 'Test::CPAN::Changes required for this test' if $@; changes_ok();