RT#71513: Card tokenization [refund test expansion]
authorJonathan Prykop <jonathan@freeside.biz>
Mon, 12 Dec 2016 18:06:38 +0000 (12:06 -0600)
committerJonathan Prykop <jonathan@freeside.biz>
Mon, 12 Dec 2016 18:06:38 +0000 (12:06 -0600)
FS/t/suite/14-tokenization_refund.t

index 65202fd..1a0f840 100755 (executable)
@@ -8,7 +8,7 @@ use FS::cust_main;
 use Business::CreditCard qw(generate_last_digit);
 use DateTime;
 if ( stat('/usr/local/etc/freeside/cardfortresstest.txt') ) {
 use Business::CreditCard qw(generate_last_digit);
 use DateTime;
 if ( stat('/usr/local/etc/freeside/cardfortresstest.txt') ) {
-  plan tests => 33;
+  plan tests => 66;
 } else {
   plan skip_all => 'CardFortress test encryption key is not installed.';
 }
 } else {
   plan skip_all => 'CardFortress test encryption key is not installed.';
 }
@@ -23,10 +23,6 @@ my @bopconf;
 ### can only run on test database (company name "Freeside Test")
 like( $conf->config('company_name'), qr/^Freeside Test/, 'using test database' ) or BAIL_OUT('');
 
 ### can only run on test database (company name "Freeside Test")
 like( $conf->config('company_name'), qr/^Freeside Test/, 'using test database' ) or BAIL_OUT('');
 
-### database might need to be upgraded before this,
-### but doesn't matter if existing records are tokenized or not,
-### this is all about testing new record creation
-
 # these will just get in the way for now
 foreach my $apg ($fs->qsearch('agent_payment_gateway')) {
   $err = $apg->delete;
 # these will just get in the way for now
 foreach my $apg ($fs->qsearch('agent_payment_gateway')) {
   $err = $apg->delete;
@@ -62,123 +58,173 @@ gateway_password
 private_key
 /usr/local/etc/freeside/cardfortresstest.txt';
 
 private_key
 /usr/local/etc/freeside/cardfortresstest.txt';
 
-# for attempting refund post-tokenization
-my $n_cust_main;
-my $n_cust_pay;
+foreach my $voiding (0,1) {
+  my $noun = $voiding ? 'void' : 'refund';
 
 
-foreach my $tokenizing (0,1) {
+  if ($voiding) {
+    $conf->delete('disable_void_after');
+    ok( !$conf->exists('disable_void_after'), 'set disable_void_after to produce voids' ) or BAIL_OUT('');
+  } else {
+    $conf->set('disable_void_after' => '0');
+    is( $conf->config('disable_void_after'), '0', 'set disable_void_after to produce refunds' ) or BAIL_OUT('');
+  }
 
 
-  my $adj = $tokenizing ? 'tokenizable' : 'non-tokenizable';
+  # for attempting refund post-tokenization
+  my $n_cust_main;
+  my $n_cust_pay;
 
 
-  # set payment gateway
-  $conf->set('business-onlinepayment' => $bopconf[$tokenizing]);
-  is( join("\n",$conf->config('business-onlinepayment')), $bopconf[$tokenizing], "set $adj default gateway" ) or BAIL_OUT('');
+  foreach my $tokenizing (0,1) {
+    my $adj = $tokenizing ? 'tokenizable' : 'non-tokenizable';
 
 
-  if ($tokenizing) {
+    # set payment gateway
+    $conf->set('business-onlinepayment' => $bopconf[$tokenizing]);
+    is( join("\n",$conf->config('business-onlinepayment')), $bopconf[$tokenizing], "set $adj $noun default gateway" ) or BAIL_OUT('');
 
 
-    my $n_paynum = $n_cust_pay->paynum;
+    # make sure we're upgraded, only need to do it once,
+    # use non-tokenizing gateway for speed,
+    # but doesn't matter if existing records are tokenized or not,
+    # this suite is all about testing new record creation
+    if (!$tokenizing && !$voiding) {
+      $err = system('freeside-upgrade','-q','admin');
+      ok( !$err, 'upgrade freeside' ) or BAIL_OUT('Error string: '.$!);
+    }
 
 
-    # refund the previous non-tokenized payment through CF
-    $err = $n_cust_main->realtime_refund_bop({
-      reasonnum => $reason->reasonnum,
-      paynum    => $n_paynum,
-      method    => 'CC',
-    });
-    ok( !$err, "run post-switch refund" ) or BAIL_OUT($err);
+    if ($tokenizing) {
 
 
-    # check for void record
-    my $n_cust_pay_void = $fs->qsearchs('cust_pay_void',{ paynum => $n_paynum });
-    isa_ok( $n_cust_pay_void, 'FS::cust_pay_void', 'post-switch void') or BAIL_OUT("paynum $n_paynum");
+      my $n_paynum = $n_cust_pay->paynum;
 
 
-    # check that void tokenized
-    ok ( $n_cust_pay_void->tokenized, "post-switch void tokenized" ) or BAIL_OUT("paynum $n_paynum");
+      # refund the previous non-tokenized payment through CF
+      $err = $n_cust_main->realtime_refund_bop({
+        reasonnum => $reason->reasonnum,
+        paynum    => $n_paynum,
+        method    => 'CC',
+      });
+      ok( !$err, "run post-switch $noun" ) or BAIL_OUT($err);
 
 
-    # check for no refund record
-    ok( !$fs->qsearch('cust_refund',{ source_paynum => $n_paynum }), "post-switch refund did not generate cust_refund" ) or BAIL_OUT("paynum $n_paynum");
+      my $n_cust_pay_void = $fs->qsearchs('cust_pay_void',{ paynum => $n_paynum });
+      my $n_cust_refund   = $fs->qsearchs('cust_refund',{ source_paynum => $n_paynum });
 
 
-  }
+      if ($voiding) {
 
 
-  # create customer
-  my $cust_main = $fs->new_customer($adj);
-  isa_ok ( $cust_main, 'FS::cust_main', "$adj customer" ) or BAIL_OUT('');
-
-  # insert customer
-  $err = $cust_main->insert;
-  ok( !$err, "insert $adj customer" ) or BAIL_OUT($err);
-
-  # add card
-  my $cust_payby;
-  my %card = random_card();
-  $err = $cust_main->save_cust_payby(
-    %card,
-    payment_payby => $card{'payby'},
-    auto => 1,
-    saved_cust_payby => \$cust_payby
-  );
-  ok( !$err, "save $adj card" ) or BAIL_OUT($err);
+        # check for void record
+        isa_ok( $n_cust_pay_void, 'FS::cust_pay_void', 'post-switch void') or BAIL_OUT("paynum $n_paynum");
 
 
-  # retrieve card
-  isa_ok ( $cust_payby, 'FS::cust_payby', "$adj card" ) or BAIL_OUT('');
+        # check that void tokenized
+        ok ( $n_cust_pay_void->tokenized, "post-switch void tokenized" ) or BAIL_OUT("paynum $n_paynum");
 
 
-  # check that card tokenized or not
-  if ($tokenizing) {
-    ok( $cust_payby->tokenized, 'new cust card tokenized' ) or BAIL_OUT('');
-  } else {
-    ok( !$cust_payby->tokenized, 'new cust card not tokenized' ) or BAIL_OUT('');
-  }
+        # check for no refund record
+        ok( !$n_cust_refund, "post-switch void did not generate cust_refund" ) or BAIL_OUT("paynum $n_paynum");
+
+      } else {
+
+        # check for refund record
+        isa_ok( $n_cust_refund, 'FS::cust_refund', 'post-switch refund') or BAIL_OUT("paynum $n_paynum");
+
+        # check that refund tokenized
+        ok ( $n_cust_refund->tokenized, "post-switch refund tokenized" ) or BAIL_OUT("paynum $n_paynum");
+
+        # check for no refund record
+        ok( !$n_cust_pay_void, "post-switch refund did not generate cust_pay_void" ) or BAIL_OUT("paynum $n_paynum");
+
+      }
 
 
-  # run a payment
-  $err = $cust_main->realtime_cust_payby( amount => '1.00' );
-  ok( !$err, "run $adj payment" ) or BAIL_OUT($err);
+    }
 
 
-  # get the payment
-  my $cust_pay = $fs->qsearchs('cust_pay',{ custnum => $cust_main->custnum }); 
-  isa_ok ( $cust_pay, 'FS::cust_pay', "$adj payment" ) or BAIL_OUT('');
+    # create customer
+    my $cust_main = $fs->new_customer($adj.'X'.$noun);
+    isa_ok ( $cust_main, 'FS::cust_main', "$adj $noun customer" ) or BAIL_OUT('');
+
+    # insert customer
+    $err = $cust_main->insert;
+    ok( !$err, "insert $adj $noun customer" ) or BAIL_OUT($err);
+
+    # add card
+    my $cust_payby;
+    my %card = random_card();
+    $err = $cust_main->save_cust_payby(
+      %card,
+      payment_payby => $card{'payby'},
+      auto => 1,
+      saved_cust_payby => \$cust_payby
+    );
+    ok( !$err, "save $adj $noun card" ) or BAIL_OUT($err);
+
+    # retrieve card
+    isa_ok ( $cust_payby, 'FS::cust_payby', "$adj $noun card" ) or BAIL_OUT('');
+
+    # check that card tokenized or not
+    if ($tokenizing) {
+      ok( $cust_payby->tokenized, "new $noun cust card tokenized" ) or BAIL_OUT('');
+    } else {
+      ok( !$cust_payby->tokenized, "new $noun cust card not tokenized" ) or BAIL_OUT('');
+    }
 
 
-  # refund the payment
-  $err = $cust_main->realtime_refund_bop({
-    reasonnum => $reason->reasonnum,
-    paynum    => $cust_pay->paynum,
-    method    => 'CC',
-  });
-  ok( !$err, "run $adj refund" ) or BAIL_OUT($err);
+    # run a payment
+    $err = $cust_main->realtime_cust_payby( amount => '1.00' );
+    ok( !$err, "run $adj $noun payment" ) or BAIL_OUT($err);
 
 
-  unless ($tokenizing) {
+    # get the payment
+    my $cust_pay = $fs->qsearchs('cust_pay',{ custnum => $cust_main->custnum }); 
+    isa_ok ( $cust_pay, 'FS::cust_pay', "$adj $noun payment" ) or BAIL_OUT('');
 
 
-    # run a second payment, to refund after switch
-    $err = $cust_main->realtime_cust_payby( amount => '2.00' );
-    ok( !$err, "run $adj second payment" ) or BAIL_OUT($err);
+    # refund the payment
+    $err = $cust_main->realtime_refund_bop({
+      reasonnum => $reason->reasonnum,
+      paynum    => $cust_pay->paynum,
+      method    => 'CC',
+    });
+    ok( !$err, "run $adj $noun" ) or BAIL_OUT($err);
+
+    unless ($tokenizing) {
+
+      # run a second payment, to refund after switch
+      $err = $cust_main->realtime_cust_payby( amount => '2.00' );
+      ok( !$err, "run $adj $noun second payment" ) or BAIL_OUT($err);
     
     
-    # get the second payment
-    $n_cust_pay = $fs->qsearchs('cust_pay',{ custnum => $cust_main->custnum, paid => '2.00' });
-    isa_ok ( $n_cust_pay, 'FS::cust_pay', "$adj second payment" ) or BAIL_OUT('');
+      # get the second payment
+      $n_cust_pay = $fs->qsearchs('cust_pay',{ custnum => $cust_main->custnum, paid => '2.00' });
+      isa_ok ( $n_cust_pay, 'FS::cust_pay', "$adj $noun second payment" ) or BAIL_OUT('');
 
 
-    $n_cust_main = $cust_main;
+      $n_cust_main = $cust_main;
 
 
-  }
+    }
 
 
-  #check that all transactions tokenized or not
-  foreach my $table (qw(cust_pay_pending cust_pay cust_pay_void)) {
-    foreach my $record ($fs->qsearch($table,{ custnum => $cust_main->custnum })) {
-      if ($tokenizing) {
-        $err = "record not tokenized: $table ".$record->get($record->primary_key)
-          unless $record->tokenized;
-      } else {
-        $err = "record tokenized: $table ".$record->get($record->primary_key)
-          if $record->tokenized;
+    #check that all transactions tokenized or not
+    foreach my $table (qw(cust_pay_pending cust_pay cust_pay_void cust_refund)) {
+      foreach my $record ($fs->qsearch($table,{ custnum => $cust_main->custnum })) {
+        if ($tokenizing) {
+          $err = "record not tokenized: $table ".$record->get($record->primary_key)
+            unless $record->tokenized;
+        } else {
+          $err = "record tokenized: $table ".$record->get($record->primary_key)
+            if $record->tokenized;
+        }
+        last if $err;
       }
       }
-      last if $err;
     }
     }
-  }
-  ok( !$err, "$adj transaction token check" ) or BAIL_OUT($err);
+    ok( !$err, "$adj transaction token check" ) or BAIL_OUT($err);
+
+    if ($voiding) {
+
+      #make sure we voided
+      ok( $fs->qsearch('cust_pay_void',{ custnum => $cust_main->custnum}), "$adj $noun record found" ) or BAIL_OUT('');
+
+      #make sure we didn't generate refund records
+      ok( !$fs->qsearch('cust_refund',{ custnum => $cust_main->custnum}), "$adj $noun did not generate cust_refund" ) or BAIL_OUT('');
 
 
-  #make sure we voided
-  ok( $fs->qsearch('cust_pay_void',{ custnum => $cust_main->custnum}), "$adj refund voided" ) or BAIL_OUT('');
+    } else {
+
+      #make sure we refunded
+      ok( $fs->qsearch('cust_refund',{ custnum => $cust_main->custnum}), "$adj $noun record found" ) or BAIL_OUT('');
+
+      #make sure we didn't generate void records
+      ok( !$fs->qsearch('cust_pay_void',{ custnum => $cust_main->custnum}), "$adj $noun did not generate cust_pay_void" ) or BAIL_OUT('');
+
+    }
 
 
-  #make sure we didn't generate refund records
-  ok( !$fs->qsearch('cust_refund',{ custnum => $cust_main->custnum}), "$adj refund did not generate cust_refund" ) or BAIL_OUT('');
+  } #end of tokenizing or not
 
 
-};
+} # end of voiding or not
 
 exit;
 
 
 exit;