Fix fatal error calling ->info(supported_actions) on a gateway that does not yet...
authorivan <ivan>
Fri, 29 Jul 2011 19:44:54 +0000 (19:44 +0000)
committerivan <ivan>
Fri, 29 Jul 2011 19:44:54 +0000 (19:44 +0000)
Changes
OnlinePayment.pm
t/introspection.t [new file with mode: 0644]

diff --git a/Changes b/Changes
index 813dced..1fe256f 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,9 +1,11 @@
 Revision history for Perl extension Business::OnlinePayment.
 
 3.02    unreleased
-        - doc fix for recurring_billing flag
+        - Fix fatal error calling ->info('supported_actions') on a gateway that
+          does not yet support introspection (e.g. AuthorizeNet)
+        - Documentation fix for recurring_billing flag
         - Add optional transaction field to documentation: currency
-        - fix spelling mistake in preCharge.pm, thanks to gregor herrmann,
+        - Fix spelling mistake in preCharge.pm POD, thanks to gregor herrmann,
           Closes: CPAN#69647
 
 3.01    Wed Jul 14 13:54:57 PDT 2010
index ceb9c74..8c421e1 100644 (file)
@@ -6,7 +6,7 @@ use Carp;
 
 require 5.005;
 
-$VERSION = '3.02_00';
+$VERSION = '3.02_02';
 $VERSION = eval $VERSION; # modperlstyle: convert the string into a number
 
 # Remember subclasses we have "wrapped" submit() with _pre_submit()
@@ -50,15 +50,15 @@ sub _info {
 %_info_handler = (
   'supported_types'   => sub {
     my( $class, $v ) = @_;
-    my $types = ref($v) ? $v : [ $v ];
-    $types = { map { $_=>1 } @$types } if ref($v) eq 'ARRAY';
+    my $types = ref($v) ? $v : defined($v) ? [ $v ] : [];
+    $types = { map { $_=>1 } @$types } if ref($types) eq 'ARRAY';
     $types;
   },
   'supported_actions' => sub {
     my( $class, $v ) = @_;
     return $v if ref($v) eq 'HASH';
     $v = [ $v ] unless ref($v);
-    my $types = $class->info('supported_types');
+    my $types = $class->info('supported_types') || {};
     { map { $_ => $v } keys %$types };
   },
 );
diff --git a/t/introspection.t b/t/introspection.t
new file mode 100644 (file)
index 0000000..de68a10
--- /dev/null
@@ -0,0 +1,72 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Test::More tests => 9;
+
+{    # fake test driver 1 (no _info hash)
+
+    package Business::OnlinePayment::MOCK1;
+    use strict;
+    use warnings;
+    use base qw(Business::OnlinePayment);
+}
+
+{    # fake test driver 2 (with _info hash)
+
+    package Business::OnlinePayment::MOCK2;
+    use base qw(Business::OnlinePayment::MOCK1);
+    sub _info {
+      {
+        'info_compat'           => '0.01', # always 0.01 for now,
+                                           # 0.02 will have requirements
+        'gateway_name'          => 'Example Gateway',
+        'gateway_url'           => 'http://www.example.com/',
+        'module_version'        => '0.01', #$VERSION,
+        'supported_types'       => [ qw( CC ECHECK ) ],
+        'token_support'         => 0, #card storage/tokenization support
+        'test_transaction'      => 0, #set true if ->test_transaction(1) works
+        'supported_actions'     => [
+                                     'Normal Authorization',
+                                     'Authorization Only',
+                                     'Post Authorization',
+                                     'Void',
+                                     'Credit',
+                                   ],
+        'CC_void_requires_card' => 1,
+      };
+    }
+}
+
+my $package = "Business::OnlinePayment";
+my @drivers = qw(MOCK1 MOCK2);
+my $driver  = $drivers[0];
+
+# trick to make use() happy (called in Business::OnlinePayment->new)
+foreach my $drv (@drivers) {
+    $INC{"Business/OnlinePayment/${drv}.pm"} = "testing";
+}
+
+
+my $obj = $package->new($driver);
+isa_ok( $obj, $package );
+isa_ok( $obj, $package . "::" . $driver );
+
+my %throwaway_actions = eval { $obj->info('supported_actions') };
+ok( !$@, "->info('supported_actions') works w/o gateway module introspection");
+
+
+$driver = 'MOCK2';
+$obj = $package->new($driver);
+isa_ok( $obj, $package );
+isa_ok( $obj, $package . "::" . $driver );
+
+my %actions = eval { $obj->info('supported_actions') };
+ok( grep { $_ eq 'Void' } @{ $actions{$_} },
+    "->info('supported_actions') works w/gateway module introspection ($_)"
+  ) foreach qw( CC ECHECK );
+
+ok($obj->info('CC_void_requires_card'),
+   'CC_void_requires_card introspection');
+ok(!$obj->info('ECHECK_void_requires_account'),
+   'ECHECK_void_requires_account introspection');