From 1e90419f5b23ab4b4fe17b5861958d75ac285c4d Mon Sep 17 00:00:00 2001 From: Alex Brelsfoard Date: Mon, 9 Feb 2015 11:58:10 -0500 Subject: [PATCH] Getting code ready for CPAN and debian relase. --- .gitignore | 6 ++ Changes | 5 ++ MANIFEST | 14 ++--- test.pl => extra/test.pl | 34 +++++------- ignore.txt | 12 ++++ .../Business/OnlinePayment/vSecureProcessing.pm | 23 ++++---- t/lib/test_account.pl | 29 ++++++++++ t/t_00-load.t | 10 ++++ t/t_boilerplate.t | 49 +++++++++++++++++ t/t_manifest.t | 13 +++++ t/t_pod-coverage.t | 18 ++++++ t/t_pod.t | 12 ++++ t/t_transaction.t | 64 ++++++++++++++++++++++ t/t_transaction_decline.t | 46 ++++++++++++++++ 14 files changed, 298 insertions(+), 37 deletions(-) create mode 100644 .gitignore create mode 100644 Changes rename test.pl => extra/test.pl (77%) create mode 100644 ignore.txt rename vSecureProcessing.pm => lib/Business/OnlinePayment/vSecureProcessing.pm (96%) create mode 100644 t/lib/test_account.pl create mode 100644 t/t_00-load.t create mode 100644 t/t_boilerplate.t create mode 100644 t/t_manifest.t create mode 100644 t/t_pod-coverage.t create mode 100644 t/t_pod.t create mode 100644 t/t_transaction.t create mode 100644 t/t_transaction_decline.t diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9788afa --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +blib/ +*.sw? +Makefile +Makefile.old +MYMETA.yml +pm_to_blib diff --git a/Changes b/Changes new file mode 100644 index 0000000..716346c --- /dev/null +++ b/Changes @@ -0,0 +1,5 @@ +Revision history for Perl module Business::OnlinePayment::vSecureProcessing + +0.01 Feb 06 2015 + Initial release. + diff --git a/MANIFEST b/MANIFEST index 2c03f96..df6a903 100644 --- a/MANIFEST +++ b/MANIFEST @@ -4,10 +4,10 @@ Makefile.PL README ignore.txt lib/Business/OnlinePayment/vSecureProcessing.pm -t/00-load.t -t/boilerplate.t -t/manifest.t -t/pod-coverage.t -t/pod.t -t/transaction.t -t/transaction_decline.t +t/t_00-load.t +t/t_boilerplate.t +t/t_manifest.t +t/t_pod-coverage.t +t/t_pod.t +t/t_transaction.t +t/t_transaction_decline.t diff --git a/test.pl b/extra/test.pl similarity index 77% rename from test.pl rename to extra/test.pl index 40f528b..bca3628 100755 --- a/test.pl +++ b/extra/test.pl @@ -6,6 +6,7 @@ # use strict; +use Data::Dumper; use Business::OnlinePayment; my %opt = ( @@ -44,32 +45,35 @@ sub main { my $transaction = Business::OnlinePayment->new("vSecureProcessing", %opt); print "MAKING PAYMENT\n"; - MakPayment($transaction); + ProcessTransaction($transaction); $content{'action'} = 'void'; - $content{'reference_number'} = $transaction->authorization; - $content{'transaction_date'} = $transaction->txn_date; + $content{'ref_num'} = $transaction->authorization(); + $content{'txn_date'} = $transaction->txn_date(); $content{'amount'} = $transaction->txn_amount; print "VOIDING PAYMENT\n"; - VoidPayment($transaction); + ProcessTransaction($transaction); $content{'action'} = 'Normal Authorization'; + $content{'amount'} = '30.00'; print "MAKING PAYMENT\n"; - MakePayment($transaction); - print "REFUNDING PAYMENT\n"; + ProcessTransaction($transaction); $content{'action'} = 'credit'; - $content{'reference_number'} = $transaction->authorization; - $content{'transaction_date'} = $transaction->txn_date; + $content{'ref_num'} = $transaction->authorization; + $content{'txn_date'} = $transaction->txn_date; $content{'amount'} = $transaction->txn_amount; - refundPayment($transaction); + print "REFUNDING PAYMENT\n"; + ProcessTransaction($transaction); } -sub MakePayment { +sub ProcessTransaction { + my $transaction = shift; + print "Processing transaction with content:\n".Dumper(\%content)."\n"; $transaction->content(%content); eval { $transaction->submit(); }; if ( $@ ) { - print "Error: $@\n"; + die "Error: $@\n"; } else { @@ -81,14 +85,6 @@ sub MakePayment { } } -sub VoidPayment { - -} - -sub RefundPayment { - -} - sub expiration_date { my($month, $year) = (localtime)[4,5]; diff --git a/ignore.txt b/ignore.txt new file mode 100644 index 0000000..997590b --- /dev/null +++ b/ignore.txt @@ -0,0 +1,12 @@ +blib* +Makefile +Makefile.old +Build +Build.bat +_build* +pm_to_blib* +*.tar.gz +.lwpcookies +cover_db +pod2htm*.tmp +Business-OnlinePayment-vSecureProcessing-* \ No newline at end of file diff --git a/vSecureProcessing.pm b/lib/Business/OnlinePayment/vSecureProcessing.pm similarity index 96% rename from vSecureProcessing.pm rename to lib/Business/OnlinePayment/vSecureProcessing.pm index 3c73067..e7514a3 100644 --- a/vSecureProcessing.pm +++ b/lib/Business/OnlinePayment/vSecureProcessing.pm @@ -87,8 +87,8 @@ sub set_defaults { # result_code, error_message, $self->build_subs(qw/ - env platform userid gid tid appid action cvv_response - avs_response risk_score txn_amount txn_date + env platform userid gid tid appid action reference_number cvv_response + avs_response risk_score txn_amount txn_date response_code /); $DEBUG = exists($options{debug}) ? $options{debug} : $DEBUG; @@ -323,20 +323,21 @@ sub parse_response { if ($self->server_response =~ /^200/) { my $response = XMLin($page); - warn "RESPONSE: \n".Dumper($response)."\n"; - $self->result_code($response->{Status}); - $self->avs_response($response->{AvsResponse}); - $self->cvv_response($response->{CvvResponse}); - $self->txn_date($response->{TransactionDate}); - $self->txn_amount($response->{TransactionAmount} / 100); - $self->cvv_response($response->{CvvResponse}); + $self->result_code($response->{Status}); # 0 /1 + $self->response_code($response->{ResponseCode}); # see documentation for translation + $self->avs_response($response->{AvsResponse}); # Y / N + $self->cvv_response($response->{CvvResponse}); # P / F + $self->txn_date($response->{TransactionDate}); # MMDDhhmmss + $self->txn_amount($response->{TransactionAmount} / 100); # 00000003500 / 100 + $self->reference_number($response->{ReferenceNumber}); + $self->is_success($self->result_code() eq '0' ? 1 : 0); if ($self->is_success()) { $self->authorization($response->{AuthIdentificationResponse}); } # fill in error_message if there is is an error - if ( !$self->is_success && exists($response->{ResultCode})) { - $self->error_message('Error '.$response->{ResponseCode}.': '.$response->{ResultCode}); + if ( !$self->is_success && exists($response->{AdditionalResponseData})) { + $self->error_message('Error '.$response->{ResponseCode}.': '.$response->{AdditionalResponseData}); }elsif ( !$self->is_success && exists($response->{Receipt}) ) { $self->error_message('Error '.$response->{ResponseCode}.': '.(exists($response->{Receipt})) ? $response->{Receipt} : ''); } diff --git a/t/lib/test_account.pl b/t/lib/test_account.pl new file mode 100644 index 0000000..69f8c89 --- /dev/null +++ b/t/lib/test_account.pl @@ -0,0 +1,29 @@ + +sub test_account { + # fill all these fields in to test out transactions + my %opts = ( + server =>'', # be sure to leave out the 'https://' + platform => '', + gid => '', + tid => '', + userid=> 'name@server.com', + port => 443, + env => 'test', + appid => '' + ); + + return %opts; +} + +sub expiration_date { + my($month, $year) = (localtime)[4,5]; + $month += 1; + $year++; # So we expire next year. + $year %= 100; + + return sprintf("%02d/%02d", $month, $year); +} + + +1; + diff --git a/t/t_00-load.t b/t/t_00-load.t new file mode 100644 index 0000000..a79fa22 --- /dev/null +++ b/t/t_00-load.t @@ -0,0 +1,10 @@ +#!perl -T + +use Test::More tests => 1; + +BEGIN { + use_ok( 'Business::OnlinePayment::vSecureProcessing' ) || print "Bail out! +"; +} + +diag( "Testing Business::OnlinePayment::vSecureProcessing $Business::OnlinePayment::vSecureProcessing::VERSION, Perl $], $^X" ); diff --git a/t/t_boilerplate.t b/t/t_boilerplate.t new file mode 100644 index 0000000..50696af --- /dev/null +++ b/t/t_boilerplate.t @@ -0,0 +1,49 @@ +#!perl -T + +use strict; +use warnings; +use Test::More tests => 3; + +sub not_in_file_ok { + my ($filename, %regex) = @_; + open( my $fh, '<', $filename ) + or die "couldn't open $filename for reading: $!"; + + my %violated; + + while (my $line = <$fh>) { + while (my ($desc, $regex) = each %regex) { + if ($line =~ $regex) { + push @{$violated{$desc}||=[]}, $.; + } + } + } + + if (%violated) { + fail("$filename contains boilerplate text"); + diag "$_ appears on lines @{$violated{$_}}" for keys %violated; + } else { + pass("$filename contains no boilerplate text"); + } +} + +sub module_boilerplate_ok { + my ($module) = @_; + not_in_file_ok($module => + 'the great new $MODULENAME' => qr/ - The great new /, + 'boilerplate description' => qr/Quick summary of what the module/, + 'stub function definition' => qr/function[12]/, + ); +} + + not_in_file_ok(README => + "The README is used..." => qr/The README is used/, + "'version information here'" => qr/to provide version information/, + ); + + not_in_file_ok(Changes => + "placeholder date/time" => qr(Date/time) + ); + + module_boilerplate_ok('lib/Business/OnlinePayment/vSecureProcessing.pm'); + diff --git a/t/t_manifest.t b/t/t_manifest.t new file mode 100644 index 0000000..45eb83f --- /dev/null +++ b/t/t_manifest.t @@ -0,0 +1,13 @@ +#!perl -T + +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +eval "use Test::CheckManifest 0.9"; +plan skip_all => "Test::CheckManifest 0.9 required" if $@; +ok_manifest(); diff --git a/t/t_pod-coverage.t b/t/t_pod-coverage.t new file mode 100644 index 0000000..c021dd4 --- /dev/null +++ b/t/t_pod-coverage.t @@ -0,0 +1,18 @@ +use strict; +use warnings; +use Test::More skip_all => "don't care about POD coverage right now"; + +# Ensure a recent version of Test::Pod::Coverage +my $min_tpc = 1.08; +eval "use Test::Pod::Coverage $min_tpc"; +plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage" + if $@; + +# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version, +# but older versions don't recognize some common documentation styles +my $min_pc = 0.18; +eval "use Pod::Coverage $min_pc"; +plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage" + if $@; + +all_pod_coverage_ok(); diff --git a/t/t_pod.t b/t/t_pod.t new file mode 100644 index 0000000..ee8b18a --- /dev/null +++ b/t/t_pod.t @@ -0,0 +1,12 @@ +#!perl -T + +use strict; +use warnings; +use Test::More; + +# Ensure a recent version of Test::Pod +my $min_tp = 1.22; +eval "use Test::Pod $min_tp"; +plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; + +all_pod_files_ok(); diff --git a/t/t_transaction.t b/t/t_transaction.t new file mode 100644 index 0000000..401797e --- /dev/null +++ b/t/t_transaction.t @@ -0,0 +1,64 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use POSIX qw(strftime); +use Test::More; +use Business::OnlinePayment; +require "t/lib/test_account.pl"; + +my %opts = test_account_or_skip('card'); + +if (!$opt{'gid'} || !$opt{'appid'}) { + plan skip_all => "no test credentials provided; fill out t/lib/test_account.pl to test communication with the gateway.", + 1; + exit(0); +} + +plan tests => 2; + +### +# Purchase +### +my %content = ( + appid => $opts{'appid'}, + action => 'Normal Authorization', + description => 'Business::OnlinePayment visa test', + card_number => '4111111111111111', + cvv2 => '111', + expiration => expiration_date(), + amount => '24.42', + name => 'Murphy Law', + email => 'fake@acme.com', + address => '123 Anystreet', + zip => '84058', +); + +my $tx = new Business::OnlinePayment( 'vSecureProcessing', \%opts ); + +$tx->content( %content, + action => 'Normal Authorization' ); + +$tx->test_transaction(1); + +$tx->submit; + +is( $tx->is_success, 1, 'purchase' ) + or diag('Gateway error: '. $tx->error_message); + +### +# Refund +### +my $auth = $tx->authorization; +$tx = new Business::OnlinePayment( 'vSecureProcessing' ); +$tx->content( %content, + action => 'Credit', + authorization => $auth ); +$tx->test_transaction(1); + +$tx->submit; + +is( $tx->is_success, 1, 'refund' ) + or diag('Gateway error: '. $tx->error_message); + +1; diff --git a/t/t_transaction_decline.t b/t/t_transaction_decline.t new file mode 100644 index 0000000..1309c78 --- /dev/null +++ b/t/t_transaction_decline.t @@ -0,0 +1,46 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use POSIX qw(strftime); +use Test::More; +use Business::OnlinePayment; +require "t/lib/test_account.pl"; + +my %opts = test_account_or_skip('card'); + +if (!$opt{'gid'} || !$opt{'appid'}) { + plan skip_all => "no test credentials provided; fill out t/lib/test_account.pl to test communication with the gateway.", + 1; + exit(0); +} + +plan tests => 2; +my %content = ( + appid => $opts{'appid'}, + action => 'Normal Authorization', + description => 'Business::OnlinePayment visa test', + card_number => '4111111111111112', # trigger failure + cvv2 => '111', + expiration => expiration_date(), + amount => '24.42', + name => 'Murphy Law', + email => 'fake@acme.com', + address => '123 Anystreet', + zip => '84058', +); + +my $tx = new Business::OnlinePayment( 'vSecureProcessing', \%opts ); + +$tx->content( %content ); + +$tx->test_transaction(1); + +$tx->submit; + +is( $tx->is_success, 0, 'declined purchase') + or diag('Test transaction should have failed, but succeeded'); +is( $tx->failure_status, 'nsf', 'failure status' ) + or diag('Failure status reported as '.$tx->failure_status); + +1; -- 2.11.0