Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 402] [Versions 311 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Testing helper class methods in payments API
  19   *
  20   * @package    core_payment
  21   * @category   test
  22   * @copyright  2020 Marina Glancy
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  namespace core_payment;
  27  
  28  use advanced_testcase;
  29  use core\plugininfo\paygw;
  30  
  31  /**
  32   * Testing helper class methods in payments API
  33   *
  34   * @package    core_payment
  35   * @category   test
  36   * @copyright  2020 Marina Glancy
  37   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  38   */
  39  class helper_test extends advanced_testcase {
  40  
  41      protected function enable_paypal_gateway(): bool {
  42          if (!array_key_exists('paypal', \core_component::get_plugin_list('paygw'))) {
  43              return false;
  44          }
  45          return true;
  46      }
  47  
  48      public function test_create_account() {
  49          global $DB;
  50          $this->resetAfterTest();
  51  
  52          $account = helper::save_payment_account((object)['name' => 'Test 1', 'idnumber' => '']);
  53          $this->assertNotEmpty($account->get('id'));
  54          $this->assertEquals('Test 1', $DB->get_field('payment_accounts', 'name', ['id' => $account->get('id')]));
  55      }
  56  
  57      public function test_update_account_details() {
  58          global $DB;
  59          $this->resetAfterTest();
  60  
  61          $account = helper::save_payment_account((object)['name' => 'Test 1', 'idnumber' => '']);
  62          $record = $account->to_record();
  63          $record->name = 'Edited name';
  64          $editedaccount = helper::save_payment_account($record);
  65          $this->assertEquals($account->get('id'), $editedaccount->get('id'));
  66          $this->assertEquals('Edited name', $DB->get_field('payment_accounts', 'name', ['id' => $account->get('id')]));
  67      }
  68  
  69      public function test_update_account_gateways() {
  70          global $DB;
  71          if (!$this->enable_paypal_gateway()) {
  72              $this->markTestSkipped('Paypal payment gateway plugin not found');
  73          }
  74  
  75          $this->resetAfterTest();
  76  
  77          $account = helper::save_payment_account((object)['name' => 'Test 1', 'idnumber' => '']);
  78          $gateway = helper::save_payment_gateway(
  79              (object)['accountid' => $account->get('id'), 'gateway' => 'paypal', 'config' => 'T1']);
  80          $this->assertNotEmpty($gateway->get('id'));
  81          $this->assertEquals('T1', $DB->get_field('payment_gateways', 'config', ['id' => $gateway->get('id')]));
  82  
  83          // Update by id.
  84          $editedgateway = helper::save_payment_gateway(
  85              (object)['id' => $gateway->get('id'), 'accountid' => $account->get('id'), 'gateway' => 'paypal', 'config' => 'T2']);
  86          $this->assertEquals($gateway->get('id'), $editedgateway->get('id'));
  87          $this->assertEquals('T2', $DB->get_field('payment_gateways', 'config', ['id' => $gateway->get('id')]));
  88  
  89          // Update by account/gateway.
  90          $editedgateway = helper::save_payment_gateway(
  91              (object)['accountid' => $account->get('id'), 'gateway' => 'paypal', 'config' => 'T3']);
  92          $this->assertEquals($gateway->get('id'), $editedgateway->get('id'));
  93          $this->assertEquals('T3', $DB->get_field('payment_gateways', 'config', ['id' => $gateway->get('id')]));
  94      }
  95  
  96      public function test_delete_account() {
  97          global $DB;
  98          if (!$this->enable_paypal_gateway()) {
  99              $this->markTestSkipped('Paypal payment gateway plugin not found');
 100          }
 101          $this->resetAfterTest();
 102  
 103          // Delete account without payments, it will be deleted, gateways will also be deleted.
 104          $account = helper::save_payment_account((object)['name' => 'Test 1', 'idnumber' => '']);
 105          $gateway = helper::save_payment_gateway(
 106              (object)['accountid' => $account->get('id'), 'gateway' => 'paypal', 'config' => 'T1']);
 107  
 108          helper::delete_payment_account(account::get_record(['id' => $account->get('id')]));
 109          $this->assertEmpty($DB->get_records('payment_accounts', ['id' => $account->get('id')]));
 110          $this->assertEmpty($DB->get_records('payment_gateways', ['id' => $gateway->get('id')]));
 111      }
 112  
 113      public function test_archive_restore_account() {
 114          global $DB, $USER;
 115          $this->resetAfterTest();
 116  
 117          // Delete account with payments - it will be archived.
 118          $this->setAdminUser();
 119          $account = helper::save_payment_account((object)['name' => 'Test 1', 'idnumber' => '']);
 120          $DB->insert_record('payments', [
 121              'accountid' => $account->get('id'),
 122              'component' => 'test',
 123              'paymentarea' => 'test',
 124              'itemid' => 1,
 125              'userid' => $USER->id,
 126          ]);
 127          helper::delete_payment_account(account::get_record(['id' => $account->get('id')]));
 128          $this->assertEquals(1, $DB->get_field('payment_accounts', 'archived', ['id' => $account->get('id')]));
 129  
 130          // Restore account.
 131          helper::restore_payment_account(account::get_record(['id' => $account->get('id')]));
 132          $this->assertEquals(0, $DB->get_field('payment_accounts', 'archived', ['id' => $account->get('id')]));
 133      }
 134  
 135      /**
 136       * Provider for format_cost test
 137       *
 138       * @return array
 139       */
 140      public function get_rounded_cost_provider(): array {
 141          return [
 142              'IRR 0 surcharge' => [5.345, 'IRR', 0, 5],
 143              'IRR 12% surcharge' => [5.345, 'IRR', 12, 6],
 144              'USD 0 surcharge' => [5.345, 'USD', 0, 5.34],
 145              'USD 1% surcharge' => [5.345, 'USD', 1, 5.4],
 146          ];
 147      }
 148  
 149      /**
 150       * Provider for test_get_cost_as_string
 151       *
 152       * @return array[]
 153       */
 154      public function get_cost_as_string_provider(): array {
 155          return [
 156              'IRR 0 surcharge' => [5.345, 'IRR', 0, 'IRR'."\xc2\xa0".'5'],
 157              'IRR 12% surcharge' => [5.345, 'IRR', 12, 'IRR'."\xc2\xa0".'6'],
 158              'USD 0 surcharge' => [5.345, 'USD', 0, 'USD'."\xc2\xa0".'5.34'],
 159              'USD 1% surcharge' => [5.345, 'USD', 1, 'USD'."\xc2\xa0".'5.40'],
 160          ];
 161      }
 162  
 163      /**
 164       * Test for test_format_cost function
 165       *
 166       * @dataProvider get_rounded_cost_provider
 167       * @param float $amount
 168       * @param string $currency
 169       * @param float $surcharge
 170       * @param string $expected
 171       */
 172      public function test_get_rounded_cost(float $amount, string $currency, float $surcharge, float $expected) {
 173          $this->assertEquals($expected, helper::get_rounded_cost($amount, $currency, $surcharge));
 174      }
 175  
 176      /**
 177       * Test for get_cost_as_string function
 178       *
 179       * @dataProvider get_cost_as_string_provider
 180       * @param float $amount
 181       * @param string $currency
 182       * @param float $surcharge
 183       * @param string $expected
 184       */
 185      public function test_get_cost_as_string(float $amount, string $currency, float $surcharge, string $expected) {
 186          // Some old ICU versions have a bug, where they don't follow the CLDR and they are
 187          // missing the non-breaking-space between the currency abbreviation and the value.
 188          // i.e. it returns AUD50 instead of AU\xc2\xa050). See the following issues @ ICU:
 189          // - https://unicode-org.atlassian.net/browse/ICU-6560
 190          // - https://unicode-org.atlassian.net/browse/ICU-8853
 191          // - https://unicode-org.atlassian.net/browse/ICU-8840
 192          // It has been detected that versions prior to ICU-61.1 / ICU-62.1 come with this
 193          // problem. Noticeably Travis images (as of December 2021) use buggy ICU-60.1.
 194          // So, here, we are going to dynamically verify the behaviour and skip the
 195          // test when buggy one is found. No need to apply this to code as dar as the real
 196          // formatting is not critical for the functionality (just small glitch).
 197          if ('IRR5' === (new \NumberFormatter('en-AU', \NumberFormatter::CURRENCY))->formatCurrency(5, 'IRR')) {
 198              $this->markTestSkipped('Old ICU libraries behavior (ICU < 62), skipping this tests');
 199          }
 200          $this->assertEquals($expected, helper::get_cost_as_string($amount, $currency, $surcharge));
 201      }
 202  }