public function testFallbackByCountry()
 {
     // With 'FallbackCurrencyByCountry', we need to return a single supported currency
     TestingGenericAdapter::$acceptedCurrencies = array('USD');
     TestingGenericAdapter::$fakeGlobals = array('FallbackCurrency' => false, 'FallbackCurrencyByCountry' => true);
     $this->setUpAdapter();
     $this->adapter->addRequestData(array('country' => 'US'));
     $this->page->validateForm();
     $this->assertEquals(100, $this->adapter->getData_Unstaged_Escaped('amount'));
     $this->assertEquals('USD', $this->adapter->getData_Unstaged_Escaped('currency_code'));
 }
 /**
  * Get the expected XML request from GlobalCollect
  *
  * @return string	The expected XML request
  */
 public function getExpectedXmlRequestForGlobalCollect($optionsForTestData, $options = array())
 {
     $orderId = $this->gatewayAdapter->getData_Unstaged_Escaped('order_id');
     $expected = '<?xml version="1.0"?>' . "\n";
     $expected .= '<XML>';
     $expected .= '<REQUEST>';
     $expected .= '<ACTION>INSERT_ORDERWITHPAYMENT</ACTION>';
     $expected .= '<META><MERCHANTID>' . $this->gatewayAdapter->getGlobal('MerchantID') . '</MERCHANTID><VERSION>1.0</VERSION></META>';
     $expected .= '<PARAMS>';
     $expected .= '<ORDER>';
     $expected .= '<ORDERID>' . $orderId . '</ORDERID>';
     $expected .= '<AMOUNT>' . $options['testData']['amount'] * 100 . '</AMOUNT>';
     $expected .= '<CURRENCYCODE>' . $options['testData']['currency_code'] . '</CURRENCYCODE>';
     $expected .= '<LANGUAGECODE>' . $options['testData']['language'] . '</LANGUAGECODE>';
     $expected .= '<COUNTRYCODE>' . $options['testData']['country'] . '</COUNTRYCODE>';
     $expected .= '<MERCHANTREFERENCE>' . $orderId . '</MERCHANTREFERENCE>';
     $expected .= '</ORDER>';
     $expected .= '<PAYMENT>';
     $expected .= '<PAYMENTPRODUCTID>' . $optionsForTestData['payment_product_id'] . '</PAYMENTPRODUCTID>';
     $expected .= '<AMOUNT>' . $options['testData']['amount'] * 100 . '</AMOUNT>';
     $expected .= '<CURRENCYCODE>' . $options['testData']['currency_code'] . '</CURRENCYCODE>';
     $expected .= '<LANGUAGECODE>' . $options['testData']['language'] . '</LANGUAGECODE>';
     $expected .= '<COUNTRYCODE>' . $options['testData']['country'] . '</COUNTRYCODE>';
     $expected .= '<HOSTEDINDICATOR>1</HOSTEDINDICATOR>';
     $expected .= '<RETURNURL>http://' . TESTS_HOSTNAME . '/index.php/Special:GlobalCollectGatewayResult?order_id=' . $orderId . '</RETURNURL>';
     $expected .= '<FIRSTNAME>' . $options['testData']['fname'] . '</FIRSTNAME>';
     $expected .= '<SURNAME>' . $options['testData']['lname'] . '</SURNAME>';
     $expected .= '<STREET>' . $options['testData']['street'] . '</STREET>';
     $expected .= '<CITY>' . $options['testData']['city'] . '</CITY>';
     $expected .= '<STATE>' . $options['testData']['state'] . '</STATE>';
     $expected .= '<EMAIL>' . TESTS_EMAIL . '</EMAIL>';
     // Set the issuer id if it is passed.
     if (isset($optionsForTestData['issuer_id'])) {
         $expected .= '<ISSUERID>' . $optionsForTestData['issuer_id'] . '</ISSUERID>';
     }
     $expected .= '</PAYMENT>';
     $expected .= '</PARAMS>';
     $expected .= '</REQUEST>';
     $expected .= '</XML>';
     return $expected;
 }
 /**
  * Render a resultswitcher page
  */
 protected function handleResultRequest()
 {
     //no longer letting people in without these things. If this is
     //preventing you from doing something, you almost certainly want to be
     //somewhere else.
     $deadSession = false;
     if (!$this->adapter->session_hasDonorData()) {
         $deadSession = true;
     }
     $oid = $this->adapter->getData_Unstaged_Escaped('order_id');
     $request = $this->getRequest();
     $referrer = $request->getHeader('referer');
     $liberated = false;
     if ($this->adapter->session_getData('order_status', $oid) === 'liberated') {
         $liberated = true;
     }
     // XXX need to know whether we were in an iframe or not.
     global $wgServer;
     if ($this->isReturnFramed() && strpos($referrer, $wgServer) === false && !$liberated) {
         $sessionOrderStatus = $request->getSessionData('order_status');
         $sessionOrderStatus[$oid] = 'liberated';
         $request->setSessionData('order_status', $sessionOrderStatus);
         $this->logger->info("Resultswitcher: Popping out of iframe for Order ID " . $oid);
         $this->getOutput()->allowClickjacking();
         $this->getOutput()->addModules('iframe.liberator');
         return;
     }
     $this->setHeaders();
     if ($deadSession) {
         if ($this->adapter->isReturnProcessingRequired()) {
             wfHttpError(403, 'Forbidden', wfMessage('donate_interface-error-http-403')->text());
             throw new RuntimeException('Resultswitcher: Request forbidden. No active donation in the session. ' . "Adapter Order ID: {$oid}");
         }
         // If it's possible for a donation to go through without our
         // having to do additional processing in the result switcher,
         // we don't want to falsely claim it failed just because we
         // lost the session data. We also don't want to give any
         // information to scammers hitting this page with no session,
         // so we always show the thank you page. We don't want to do
         // any post-processing if we're not sure whether we actually
         // originated this attempt, so we return right after.
         $this->logger->warning('Resultswitcher: session is dead, but the ' . 'donor may have made a successful payment.');
         $this->displayThankYouPage('dead session');
         return;
     }
     $this->logger->info("Resultswitcher: OK to process Order ID: " . $oid);
     if ($this->adapter->checkTokens()) {
         $this->getOutput()->allowClickjacking();
         // FIXME: do we really need this again?
         $this->getOutput()->addModules('iframe.liberator');
         // processResponse expects some data, so let's feed it all the
         // GET and POST vars
         $response = $this->getRequest()->getValues();
         // TODO: run the whole set of getResponseStatus, getResponseErrors
         // and getResponseData first.  Maybe do_transaction with a
         // communication_type of 'incoming' and a way to provide the
         // adapter the GET/POST params harvested here.
         $this->adapter->processResponse($response);
         $status = $this->adapter->getFinalStatus();
         switch ($status) {
             case FinalStatus::COMPLETE:
             case FinalStatus::PENDING:
                 $this->displayThankYouPage($status);
                 return;
         }
         $this->logger->info("Displaying fail page for final status {$status}");
     } else {
         $this->logger->error("Resultswitcher: Token Check Failed. Order ID: {$oid}");
     }
     $this->displayFailPage();
 }
 /**
  * Pulls normalized and escaped data from the $gateway object.
  * For more information, see GatewayAdapter::getData_Unstaged_Escaped in
  * $IP/extensions/DonationData/gateway_common/gateway.adapter.php
  * @param string $key The value to fetch from the adapter.
  * @return mixed The escaped value in the adapter, or null if none exists.
  * Note: The value could still be a blank string in some cases.
  */
 protected function getEscapedValue($key)
 {
     return $this->gateway->getData_Unstaged_Escaped($key);
 }
 /**
  * Get the expected XML request from GlobalCollect
  *
  * @param $optionsForTestData
  * @param array $options
  * @return string    The expected XML request
  */
 public function getExpectedXmlRequestForGlobalCollect($optionsForTestData, $options = array())
 {
     global $wgDonationInterfaceThankYouPage;
     $request = RequestContext::getMain()->getRequest();
     $orderId = $this->gatewayAdapter->getData_Unstaged_Escaped('order_id');
     $exposed = TestingAccessWrapper::newFromObject($this->gatewayAdapter);
     $merchantref = $exposed->getData_Staged('contribution_tracking_id');
     //@TODO: WHY IN THE NAME OF ZARQUON are we building XML in a STRING format here?!?!?!!!1one1!?. Great galloping galumphing giraffes.
     $expected = '<?xml version="1.0" encoding="UTF-8"?' . ">\n";
     $expected .= '<XML>';
     $expected .= '<REQUEST>';
     $expected .= '<ACTION>INSERT_ORDERWITHPAYMENT</ACTION>';
     $expected .= '<META><MERCHANTID>' . $exposed->account_config['MerchantID'] . '</MERCHANTID>';
     if (isset($request)) {
         $expected .= '<IPADDRESS>' . $request->getIP() . '</IPADDRESS>';
     }
     $expected .= '<VERSION>1.0</VERSION>';
     $expected .= '</META>';
     $expected .= '<PARAMS>';
     $expected .= '<ORDER>';
     $expected .= '<ORDERID>' . $orderId . '</ORDERID>';
     $expected .= '<AMOUNT>' . $options['amount'] * 100 . '</AMOUNT>';
     $expected .= '<CURRENCYCODE>' . $options['currency_code'] . '</CURRENCYCODE>';
     $expected .= '<LANGUAGECODE>' . $options['language'] . '</LANGUAGECODE>';
     $expected .= '<COUNTRYCODE>' . $options['country'] . '</COUNTRYCODE>';
     $expected .= '<MERCHANTREFERENCE>' . $merchantref . '</MERCHANTREFERENCE>';
     if (isset($request)) {
         $expected .= '<IPADDRESSCUSTOMER>' . $request->getIP() . '</IPADDRESSCUSTOMER>';
     }
     $expected .= '<EMAIL>' . TESTS_EMAIL . '</EMAIL>';
     $expected .= '</ORDER>';
     $expected .= '<PAYMENT>';
     $expected .= '<PAYMENTPRODUCTID>' . $optionsForTestData['payment_product_id'] . '</PAYMENTPRODUCTID>';
     $expected .= '<AMOUNT>' . $options['amount'] * 100 . '</AMOUNT>';
     $expected .= '<CURRENCYCODE>' . $options['currency_code'] . '</CURRENCYCODE>';
     $expected .= '<LANGUAGECODE>' . $options['language'] . '</LANGUAGECODE>';
     $expected .= '<COUNTRYCODE>' . $options['country'] . '</COUNTRYCODE>';
     $expected .= '<HOSTEDINDICATOR>1</HOSTEDINDICATOR>';
     $expected .= "<RETURNURL>{$wgDonationInterfaceThankYouPage}/{$options['language']}?country={$options['country']}</RETURNURL>";
     $expected .= '<AUTHENTICATIONINDICATOR>0</AUTHENTICATIONINDICATOR>';
     $expected .= '<FIRSTNAME>' . $options['fname'] . '</FIRSTNAME>';
     $expected .= '<SURNAME>' . $options['lname'] . '</SURNAME>';
     $expected .= '<STREET>' . $options['street'] . '</STREET>';
     $expected .= '<CITY>' . $options['city'] . '</CITY>';
     $expected .= '<STATE>' . $options['state'] . '</STATE>';
     $expected .= '<ZIP>' . $options['zip'] . '</ZIP>';
     $expected .= '<EMAIL>' . TESTS_EMAIL . '</EMAIL>';
     // Set the issuer id if it is passed.
     if (isset($optionsForTestData['descriptor'])) {
         $expected .= '<DESCRIPTOR>' . $optionsForTestData['descriptor'] . '</DESCRIPTOR>';
     }
     // Set the issuer id if it is passed.
     if (isset($optionsForTestData['issuer_id'])) {
         $expected .= '<ISSUERID>' . $optionsForTestData['issuer_id'] . '</ISSUERID>';
     }
     // If we're doing Direct Debit...
     //@TODO: go ahead and split this out into a "Get the direct debit I_OWP XML block function" the second this gets even slightly annoying.
     if ($optionsForTestData['payment_method'] === 'dd') {
         $expected .= '<ACCOUNTNAME>' . $optionsForTestData['account_name'] . '</ACCOUNTNAME>';
         $expected .= '<ACCOUNTNUMBER>' . $optionsForTestData['account_number'] . '</ACCOUNTNUMBER>';
         $expected .= '<BANKCODE>' . $optionsForTestData['bank_code'] . '</BANKCODE>';
         $expected .= '<BRANCHCODE>' . $optionsForTestData['branch_code'] . '</BRANCHCODE>';
         $expected .= '<BANKCHECKDIGIT>' . $optionsForTestData['bank_check_digit'] . '</BANKCHECKDIGIT>';
         $expected .= '<DATECOLLECT>' . gmdate('Ymd') . '</DATECOLLECT>';
         //is this cheating? Probably.
         $expected .= '<DIRECTDEBITTEXT>' . $optionsForTestData['direct_debit_text'] . '</DIRECTDEBITTEXT>';
     }
     $expected .= '</PAYMENT>';
     $expected .= '</PARAMS>';
     $expected .= '</REQUEST>';
     $expected .= '</XML>';
     return $expected;
 }