jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/370225 )

Change subject: Orphan Slayer Module
......................................................................


Orphan Slayer Module

Change-Id: I1b3d1ac329ff225fdc00bf2fc534114fac617343
---
M composer.lock
M phpunit.xml
A sites/all/modules/orphan_slayer/OrphanSlayer.php
R sites/all/modules/orphan_slayer/globalcollect/orphan_rectify.drush.inc
A sites/all/modules/orphan_slayer/orphan_slayer.drush.inc
A sites/all/modules/orphan_slayer/orphan_slayer.info
A sites/all/modules/orphan_slayer/orphan_slayer.module
A sites/all/modules/orphan_slayer/tests/phpunit/OrphanSlayerTest.php
M sites/default/bootstrap-phpunit.php
M sites/default/enabled_modules
10 files changed, 224 insertions(+), 13 deletions(-)

Approvals:
  jenkins-bot: Verified
  Ejegg: Looks good to me, approved



diff --git a/composer.lock b/composer.lock
index 9ed29b5..61952fa 100644
--- a/composer.lock
+++ b/composer.lock
@@ -2576,16 +2576,16 @@
         },
         {
             "name": "phpdocumentor/reflection-common",
-            "version": "1.0",
+            "version": "1.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/ReflectionCommon.git";,
-                "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
+                "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c";,
-                "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
+                "url": 
"https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6";,
+                "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
                 "shasum": ""
             },
             "require": {
@@ -2626,7 +2626,7 @@
                 "reflection",
                 "static analysis"
             ],
-            "time": "2015-12-27T11:43:31+00:00"
+            "time": "2017-09-11T18:02:19+00:00"
         },
         {
             "name": "phpdocumentor/reflection-docblock",
@@ -2722,22 +2722,22 @@
         },
         {
             "name": "phpspec/prophecy",
-            "version": "v1.7.0",
+            "version": "v1.7.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpspec/prophecy.git";,
-                "reference": "93d39f1f7f9326d746203c7c056f300f7f126073"
+                "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073";,
-                "reference": "93d39f1f7f9326d746203c7c056f300f7f126073",
+                "url": 
"https://api.github.com/repos/phpspec/prophecy/zipball/c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6";,
+                "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6",
                 "shasum": ""
             },
             "require": {
                 "doctrine/instantiator": "^1.0.2",
                 "php": "^5.3|^7.0",
-                "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
+                "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
                 "sebastian/comparator": "^1.1|^2.0",
                 "sebastian/recursion-context": "^1.0|^2.0|^3.0"
             },
@@ -2748,7 +2748,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.6.x-dev"
+                    "dev-master": "1.7.x-dev"
                 }
             },
             "autoload": {
@@ -2781,7 +2781,7 @@
                 "spy",
                 "stub"
             ],
-            "time": "2017-03-02T20:05:34+00:00"
+            "time": "2017-09-04T11:05:03+00:00"
         },
         {
             "name": "phpunit/php-code-coverage",
diff --git a/phpunit.xml b/phpunit.xml
index 06e7423..1a40ebf 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -15,6 +15,9 @@
       <testsuite name="exchange_rates tests">
         <directory>sites/all/modules/exchange_rates/tests/phpunit</directory>
       </testsuite>
+      <testsuite name="orphan_slayer tests">
+        <directory>sites/all/modules/orphan_slayer/tests/phpunit</directory>
+      </testsuite>
       <testsuite name="queue2civicrm tests">
         <directory>sites/all/modules/queue2civicrm/tests/phpunit</directory>
       </testsuite>
diff --git a/sites/all/modules/orphan_slayer/OrphanSlayer.php 
b/sites/all/modules/orphan_slayer/OrphanSlayer.php
new file mode 100644
index 0000000..639eb2b
--- /dev/null
+++ b/sites/all/modules/orphan_slayer/OrphanSlayer.php
@@ -0,0 +1,34 @@
+<?php
+
+use SmashPig\Core\DataStores\PendingDatabase;
+
+class OrphanSlayer {
+    public $gateway;
+    protected $adapter;
+
+    public function __construct($gateway) {
+        $this->gateway = $gateway;
+    }
+
+    public function get_oldest() {
+        return 
PendingDatabase::get()->fetchMessageByGatewayOldest($this->gateway);
+    }
+
+    public function rectify($orphan) {
+        $orphan['amount'] = $orphan['gross'];
+        $this->adapter = 
DonationInterfaceFactory::createAdapter($this->gateway, $orphan);
+        $result = $this->adapter->rectifyOrphan();
+        $this->delete_orphan($orphan);
+        return $result;
+    }
+
+    public function cancel($orphan) {
+        //FIXME: Add cancel when implementing ingenico
+        $this->delete_orphan($orphan);
+    }
+
+    protected function delete_orphan($orphan) {
+        PendingDatabase::get()->deleteMessage($orphan);
+    }
+
+}
diff --git a/sites/all/modules/wmf_audit/ingenico/orphan_rectify.drush.inc 
b/sites/all/modules/orphan_slayer/globalcollect/orphan_rectify.drush.inc
similarity index 100%
rename from sites/all/modules/wmf_audit/ingenico/orphan_rectify.drush.inc
rename to sites/all/modules/orphan_slayer/globalcollect/orphan_rectify.drush.inc
diff --git a/sites/all/modules/orphan_slayer/orphan_slayer.drush.inc 
b/sites/all/modules/orphan_slayer/orphan_slayer.drush.inc
new file mode 100644
index 0000000..4eb6633
--- /dev/null
+++ b/sites/all/modules/orphan_slayer/orphan_slayer.drush.inc
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Detect and rectify recently orphaned Gateway transactions
+ */
+
+/**
+ * Implementation of hook_drush_command()
+ */
+function orphan_slayer_drush_command() {
+    $items = array();
+
+    $items['orphan-slayer'] = array(
+        'description' =>
+            'Check for orphaned Gateway transactions, and resolve.',
+        'examples' => array(
+            'drush orphan-slay' => '# Run the orphan rectifier.',
+        ),
+        'required-arguments' => 'true',
+        'arguments' => array(
+            'gateway' => 'gateway',
+        ),
+        'options' => array(
+            'time' => 'time'
+        )
+    );
+
+    return $items;
+}
+
+/**
+ * Implementation of hook_drush_help()
+ */
+function orphan_slayer_drush_help($section) {
+    switch ($section) {
+        case 'orphan_slayer':
+            return dt("Check for orphaned transactions, and resolve.");
+    }
+}
+
+/**
+ * Note: You'll need to include a bunch of exciting MediaWiki globals in your
+ * Drupal settings.local.php, including default values that would normally be
+ * read from extension.json.
+ *     $wgDonationInterfaceGatewayAdapters
+ *     $wgDonationInterfaceForbiddenCountries
+ *     $wgDonationInterface3DSRules
+ *     $wgDonationInterfacePriceFloor
+ *     $wgDonationInterfacePriceCeiling
+ *     $wgDonationInterfaceRetryLoopCount
+ * For any gateways implemented, set these globals, replacing name with the 
gateway identifier
+ *     $wg[name]GatewayEnabled
+ *     $wg[name]GatewayAccountInfo
+ *     $wg[name]GatewayURL
+
+ */
+function drush_orphan_slayer() {
+    // TODO: SmashPig and DI initialization should be reused from a higher
+    // level and integrated with app config
+    $args = drush_get_arguments();
+    $gateway = $args[1];
+    $time = drush_get_option('time', '30');
+
+    wmf_common_create_smashpig_context("gateway_orphan_slayer", "$gateway");
+    orphan_slayer_process_orphans($gateway, $time);
+}
diff --git a/sites/all/modules/orphan_slayer/orphan_slayer.info 
b/sites/all/modules/orphan_slayer/orphan_slayer.info
new file mode 100644
index 0000000..1b23ca4
--- /dev/null
+++ b/sites/all/modules/orphan_slayer/orphan_slayer.info
@@ -0,0 +1,5 @@
+name = Orphan Slayer
+description = Drush command to find what happened to orphaned transactions
+core = 7.x
+dependencies[] = wmf_civicrm
+files[] = OrphanSlayer.php
diff --git a/sites/all/modules/orphan_slayer/orphan_slayer.module 
b/sites/all/modules/orphan_slayer/orphan_slayer.module
new file mode 100644
index 0000000..0a13435
--- /dev/null
+++ b/sites/all/modules/orphan_slayer/orphan_slayer.module
@@ -0,0 +1,18 @@
+<?php
+
+use \SmashPig\Core\UtcDate;
+
+function orphan_slayer_process_orphans($gateway, $time = 30)
+{
+    $slayer = new OrphanSlayer($gateway);
+    $orphan = $slayer->get_oldest();
+    while ($orphan && ($orphan['date'] < UtcDate::getUtcTimestamp("-$time 
minutes"))) {
+        if ($orphan['contribution_tracking_id']) {
+            $result = $slayer->rectify($orphan);
+            watchdog('orphan slayer', 'orphan ' 
.$orphan['contribution_tracking_id'] . ': was rectified and the result is ' . 
print_r($result, true));
+        } else {
+            $slayer->cancel($orphan);
+        }
+        $orphan = $slayer->get_oldest();
+    }
+}
diff --git a/sites/all/modules/orphan_slayer/tests/phpunit/OrphanSlayerTest.php 
b/sites/all/modules/orphan_slayer/tests/phpunit/OrphanSlayerTest.php
new file mode 100644
index 0000000..04efe0b
--- /dev/null
+++ b/sites/all/modules/orphan_slayer/tests/phpunit/OrphanSlayerTest.php
@@ -0,0 +1,84 @@
+<?php
+
+use SmashPig\Core\Context;
+use SmashPig\Tests\TestingContext;
+use SmashPig\Tests\TestingGlobalConfiguration;
+use SmashPig\Core\DataStores\PendingDatabase;
+
+/**
+ * @group OrphanSlayer
+ */
+
+class OrphanSlayerTest extends PHPUnit_Framework_TestCase {
+
+    public function setUp() {
+        parent::setUp();
+
+        // Initialize SmashPig with a fake context object
+        $config = TestingGlobalConfiguration::create();
+        TestingContext::init( $config );
+
+        if ( !defined( 'DRUPAL_ROOT' ) ) {
+            throw new Exception( "Define DRUPAL_ROOT somewhere before running 
unit tests." );
+        }
+
+        global $user, $_exchange_rate_cache;
+        $GLOBALS['_PEAR_default_error_mode'] = NULL;
+        $GLOBALS['_PEAR_default_error_options'] = NULL;
+        $_exchange_rate_cache = array();
+
+        $user = new stdClass();
+        $user->name = "foo_who";
+        $user->uid = "321";
+        $user->roles = array( DRUPAL_AUTHENTICATED_RID => 'authenticated user' 
);
+    }
+
+    public function tearDown() {
+        Context::set( null ); // Nullify any SmashPig context for the next run
+        parent::tearDown();
+    }
+
+
+    public function testGetOldest(){
+        $slayer = new OrphanSlayer('paypal_ec');
+        $orphan = $this->createTestOrphan('paypal_ec');
+        $result = $slayer->get_oldest();
+        $this->assertEquals($orphan['contribution_tracking_id'], 
$result['contribution_tracking_id'], "Cannot get orphan");
+        PendingDatabase::get()->deleteMessage([$orphan]);
+    }
+
+    public function testrectify() {
+        $slayer = new OrphanSlayer('paypal_ec');
+        $orphan = $this->createTestOrphan($slayer->gateway);
+        TestingPaypalExpressAdapter::setDummyGatewayResponseCode('OK');
+        $result = $slayer->rectify($orphan);
+        $this->assertEquals(array(), $result->getErrors(), "rectify_orphan 
returned errors: " . print_r($result->getErrors(), true));
+        $result = PendingDatabase::get()->fetchMessageByGatewayOrderId( 
'paypal_ec', $orphan['order_id'] );
+        $this->assertEquals($result, null, "Orphan was not deleted");
+    }
+
+    protected function createTestOrphan($gateway = 'test'){
+        $uniq = mt_rand();
+        $message = array(
+            'contribution_tracking_id' => $uniq,
+            'country' => 'US',
+            'first_name' => 'Flighty',
+            'last_name' => 'Dono',
+            'email' => 'test+...@eff.org',
+            'gateway' => $gateway,
+            'gateway_txn_id' => "txn-{$uniq}",
+            'gateway_session_id' => mt_rand(),
+            'order_id' => "order-{$uniq}",
+            'gateway_account' => 'default',
+            'payment_method' => 'paypal',
+            'payment_submethod' => 'mc',
+            // Defaults to a magic 25 minutes ago, within the process window.
+            'date' => time() - 25 * 60,
+            'gross' => 123,
+            'currency' => 'EUR',
+        );
+
+        PendingDatabase::get()->storeMessage($message);
+        return $message;
+    }
+}
diff --git a/sites/default/bootstrap-phpunit.php 
b/sites/default/bootstrap-phpunit.php
index e7f2b26..e7262b4 100644
--- a/sites/default/bootstrap-phpunit.php
+++ b/sites/default/bootstrap-phpunit.php
@@ -18,6 +18,7 @@
 // Load contrib libs so tests can inherit from them.
 require_once( DRUPAL_ROOT . '/../vendor/autoload.php' );
 // And explicitly load some DonationInterface things that it doesn't export 
via Composer
+require_once(DRUPAL_ROOT . 
'/../vendor/wikimedia/donation-interface/tests/phpunit/TestConfiguration.php');
 require_once( DRUPAL_ROOT . 
'/../vendor/wikimedia/donation-interface/tests/phpunit/includes/test_gateway/test.adapter.php'
 );
 require_once( DRUPAL_ROOT . 
'/../vendor/wikimedia/donation-interface/tests/phpunit/includes/test_gateway/TestingGlobalCollectAdapter.php'
 );
 require_once( DRUPAL_ROOT . 
'/../vendor/wikimedia/donation-interface/tests/phpunit/includes/test_gateway/TestingGlobalCollectOrphanAdapter.php'
 );
@@ -27,5 +28,5 @@
 require_once DRUPAL_ROOT . 
'/sites/default/civicrm/extensions/org.wikimedia.omnimail/tests/phpunit/bootstrap.php';
 
 if ( !defined( 'PRINT_WATCHDOG_ON_TEST_FAIL' ) ) {
-       define( 'PRINT_WATCHDOG_ON_TEST_FAIL', true );
+    define( 'PRINT_WATCHDOG_ON_TEST_FAIL', true );
 }
diff --git a/sites/default/enabled_modules b/sites/default/enabled_modules
index 168aae4..b49e4e0 100644
--- a/sites/default/enabled_modules
+++ b/sites/default/enabled_modules
@@ -16,6 +16,7 @@
 oauth_common
 oauth_common_providerui
 offline2civicrm
+orphan_slayer
 queue2civicrm
 recurring
 recurring_globalcollect

-- 
To view, visit https://gerrit.wikimedia.org/r/370225
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I1b3d1ac329ff225fdc00bf2fc534114fac617343
Gerrit-PatchSet: 36
Gerrit-Project: wikimedia/fundraising/crm
Gerrit-Branch: master
Gerrit-Owner: Mepps <me...@wikimedia.org>
Gerrit-Reviewer: Ejegg <ej...@ejegg.com>
Gerrit-Reviewer: Mepps <me...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to