Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 and 403] [Versions 402 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   * User agent test suite.
  19   *
  20   * @package    core
  21   * @copyright  2013 Sam Hemelryk
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   * @covers \core_useragent
  24   */
  25  class useragent_test extends advanced_testcase {
  26  
  27      /**
  28       * Restores the user agent to the default one.
  29       */
  30      public function tearDown(): void {
  31          core_useragent::instance(true);
  32      }
  33  
  34      /**
  35       * Data provider for known user agents.
  36       *
  37       * @return array
  38       */
  39      public function user_agents_providers() {
  40          // Note: When adding new entries to this list, please ensure that any new browser versions are added to the corresponding list.
  41          // This ensures that regression tests are applied to all known user agents.
  42          return array(
  43              'Microsoft Edge for Windows 10 Desktop' => array(
  44                  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10136',
  45                  array(
  46                      'is_edge'                       => true,
  47                      'check_edge_version'            => array(
  48                          '12'                        => true,
  49                      ),
  50  
  51                      // Edge pretends to be WebKit.
  52                      'is_webkit'                     => true,
  53  
  54                      // Edge pretends to be Chrome.
  55                      // Note: Because Edge pretends to be Chrome, it will not be picked up as a Safari browser.
  56                      'is_chrome'                     => true,
  57                      'check_chrome_version'          => array(
  58                          '7'                         => true,
  59                          '8'                         => true,
  60                          '10'                        => true,
  61                          '39'                        => true,
  62                      ),
  63  
  64                      'versionclasses'                => array(
  65                          'edge',
  66                      ),
  67                  ),
  68              ),
  69              'Microsoft Edge for Windows 10 Mobile' => array(
  70                  'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; DEVICE INFO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Mobile Safari/537.36 Edge/12.10136',
  71                  array(
  72                      'is_edge'                       => true,
  73                      'check_edge_version'              => array(
  74                          '12'                        => true,
  75                      ),
  76  
  77                      // Edge pretends to be WebKit.
  78                      'is_webkit'                     => true,
  79  
  80                      // Mobile Edge pretends to be Android.
  81                      'is_webkit_android'             => true,
  82                      'check_webkit_android_version'  => array(
  83                          '525'                       => true,
  84                          '527'                       => true,
  85                      ),
  86  
  87                      // Edge pretends to be Chrome.
  88                      // Note: Because Edge pretends to be Chrome, it will not be picked up as a Safari browser.
  89                      'is_chrome'                     => true,
  90                      'check_chrome_version'          => array(
  91                          '7'                         => true,
  92                          '8'                         => true,
  93                          '10'                        => true,
  94                          '39'                        => true,
  95                      ),
  96  
  97                      'versionclasses'                => array(
  98                          'edge'
  99                      ),
 100  
 101                      'devicetype'                    => 'mobile',
 102                  ),
 103              ),
 104  
 105              // Windows XP; Firefox 1.0.6.
 106              array(
 107                  'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6',
 108                  array(
 109                      'is_firefox'                    => true,
 110  
 111                      'is_gecko'                      => true,
 112                      'check_gecko_version'           => array(
 113                          '1'                         => true,
 114                      ),
 115  
 116                      'versionclasses'                => array(
 117                          'gecko',
 118                          'gecko17',
 119                      ),
 120                  ),
 121              ),
 122  
 123              // Windows XP; Firefox 1.0.6.
 124              array(
 125                  'Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.8) Gecko/20051107 Firefox/1.5',
 126                  array(
 127                      'is_firefox'                    => true,
 128                      'check_firefox_version'         => array(
 129                          '1.5'                       => true,
 130                      ),
 131  
 132                      'is_gecko'                      => true,
 133                      'check_gecko_version'           => array(
 134                          '1'                         => true,
 135                          '20030516'                  => true,
 136                          '20051116'                  => true,
 137                      ),
 138  
 139                      'versionclasses'                => array(
 140                          'gecko',
 141                          'gecko18',
 142                      ),
 143                  ),
 144              ),
 145  
 146              // Windows XP; Firefox 1.5.0.1.
 147              array(
 148                  'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1',
 149                  array(
 150                      'is_firefox'                    => true,
 151                      'check_firefox_version'         => array(
 152                          '1.5'                       => true,
 153                      ),
 154  
 155                      'is_gecko'                      => true,
 156                      'check_gecko_version'           => array(
 157                          '1'                         => true,
 158                          '20030516'                  => true,
 159                          '20051116'                  => true,
 160                      ),
 161  
 162                      'versionclasses'                => array(
 163                          'gecko',
 164                          'gecko18',
 165                      ),
 166                  ),
 167              ),
 168  
 169              // Windows XP; Firefox 2.0.
 170              array(
 171                  'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1',
 172                  array(
 173                      'is_firefox'                    => true,
 174                      'check_firefox_version'         => array(
 175                          '1.5'                       => true,
 176                      ),
 177  
 178                      'is_gecko'                      => true,
 179                      'check_gecko_version'           => array(
 180                          '1'                         => true,
 181                          '2'                         => true,
 182                          '20030516'                  => true,
 183                          '20051116'                  => true,
 184                          '2006010100'                => true,
 185                      ),
 186  
 187                      'versionclasses'                => array(
 188                          'gecko',
 189                          'gecko18',
 190                      ),
 191                  ),
 192              ),
 193  
 194              // Ubuntu Linux amd64; Firefox 2.0.
 195              array(
 196                  'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1) Gecko/20060601 Firefox/2.0 (Ubuntu-edgy)',
 197                  array(
 198                      'is_firefox'                    => true,
 199                      'check_firefox_version'         => array(
 200                          '1.5'                       => true,
 201                      ),
 202  
 203                      'is_gecko'                      => true,
 204                      'check_gecko_version'           => array(
 205                          '1'                         => true,
 206                          '2'                         => true,
 207                          '20030516'                  => true,
 208                          '20051116'                  => true,
 209                          '2006010100'                => true,
 210                      ),
 211  
 212                      'versionclasses'                => array(
 213                          'gecko',
 214                          'gecko18',
 215                      ),
 216                  ),
 217              ),
 218  
 219              // SUSE; Firefox 3.0.6.
 220              array(
 221                  'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.6) Gecko/2009012700 SUSE/3.0.6-1.4 Firefox/3.0.6',
 222                  array(
 223                      'is_firefox'                    => true,
 224                      'check_firefox_version'         => array(
 225                          '1.5'                       => true,
 226                          '3.0'                       => true,
 227                      ),
 228  
 229                      'is_gecko'                      => true,
 230                      'check_gecko_version'           => array(
 231                          '1'                         => true,
 232                          '2'                         => true,
 233                          '20030516'                  => true,
 234                          '20051116'                  => true,
 235                          '2006010100'                => true,
 236                      ),
 237  
 238                      'versionclasses'                => array(
 239                          'gecko',
 240                          'gecko19',
 241                      ),
 242                  ),
 243              ),
 244  
 245              // Linux i686; Firefox 3.6.
 246              array(
 247                  'Mozilla/5.0 (X11; Linux i686; rv:2.0) Gecko/20100101 Firefox/3.6',
 248                  array(
 249                      'is_firefox'                    => true,
 250                      'check_firefox_version'         => array(
 251                          '1.5'                       => true,
 252                          '3.0'                       => true,
 253                      ),
 254  
 255                      'is_gecko'                      => true,
 256                      'check_gecko_version'           => array(
 257                          '1'                         => true,
 258                          '2'                         => true,
 259                          '20030516'                  => true,
 260                          '20051116'                  => true,
 261                          '2006010100'                => true,
 262                          '3.6'                       => true,
 263                          '20100101'                  => true,
 264                      ),
 265  
 266                      'versionclasses'                => array(
 267                          'gecko',
 268                          'gecko20',
 269                      ),
 270                  ),
 271              ),
 272  
 273              // Windows; Firefox 11.0.
 274              array(
 275                  'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko Firefox/11.0',
 276                  array(
 277                      'is_firefox'                    => true,
 278                      'check_firefox_version'         => array(
 279                          '1.5'                       => true,
 280                          '3.0'                       => true,
 281                          '4'                         => true,
 282                          '10'                        => true,
 283                      ),
 284  
 285                      'is_gecko'                      => true,
 286                      'check_gecko_version'           => array(
 287                          '1'                         => true,
 288                          '2'                         => true,
 289                          '20030516'                  => true,
 290                          '20051116'                  => true,
 291                          '2006010100'                => true,
 292                          '20100101'                  => true,
 293                          '3.6'                       => true,
 294                          '4.0'                       => true,
 295                      ),
 296  
 297                      'versionclasses'                => array(
 298                          'gecko',
 299                      ),
 300                  ),
 301              ),
 302  
 303              // Windows; Firefox 15.0a2.
 304              array(
 305                  'Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120716 Firefox/15.0a2',
 306                  array(
 307                      'is_firefox'                    => true,
 308                      'check_firefox_version'         => array(
 309                          '1.5'                       => true,
 310                          '3.0'                       => true,
 311                          '4'                         => true,
 312                          '10'                        => true,
 313                          '15'                        => true,
 314                      ),
 315  
 316                      'is_gecko'                      => true,
 317                      'check_gecko_version'           => array(
 318                          '1'                         => true,
 319                          '2'                         => true,
 320                          '20030516'                  => true,
 321                          '20051116'                  => true,
 322                          '2006010100'                => true,
 323                          '20100101'                  => true,
 324                          '3.6'                       => true,
 325                          '4.0'                       => true,
 326                          '15.0'                      => true,
 327                      ),
 328  
 329                      'versionclasses'                => array(
 330                          'gecko',
 331                      ),
 332                  ),
 333              ),
 334  
 335              // Firefox 18; Mac OS X 10.
 336              array(
 337                  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:18.0) Gecko/18.0 Firefox/18.0',
 338                  array(
 339                      'is_firefox'                    => true,
 340                      'check_firefox_version'         => array(
 341                          '1.5'                       => true,
 342                          '3.0'                       => true,
 343                          '4'                         => true,
 344                          '10'                        => true,
 345                          '15'                        => true,
 346                          '18'                        => true,
 347                      ),
 348  
 349                      'is_gecko'                      => true,
 350                      'check_gecko_version'           => array(
 351                          '1'                         => true,
 352                          '2'                         => true,
 353                          '20030516'                  => true,
 354                          '20051116'                  => true,
 355                          '2006010100'                => true,
 356                          '3.6'                       => true,
 357                          '4.0'                       => true,
 358                          '15.0'                      => true,
 359                          '18.0'                      => true,
 360                          '20100101'                  => true,
 361                      ),
 362  
 363                      'versionclasses'                => array(
 364                          'gecko',
 365                      ),
 366                  ),
 367              ),
 368  
 369              // Firefox 33; Mac OS X 10.10.
 370              array(
 371                  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:33.0) Gecko/20100101 Firefox/33.0',
 372                  array(
 373                      'is_firefox'                    => true,
 374                      'check_firefox_version'         => array(
 375                          '1.5'                       => true,
 376                          '3.0'                       => true,
 377                          '4'                         => true,
 378                          '10'                        => true,
 379                          '15'                        => true,
 380                          '18'                        => true,
 381                          '19'                        => true,
 382                          '33'                        => true,
 383                      ),
 384  
 385                      'is_gecko'                      => true,
 386                      'check_gecko_version'           => array(
 387                          '1'                         => true,
 388                          '2'                         => true,
 389                          '20030516'                  => true,
 390                          '20051116'                  => true,
 391                          '2006010100'                => true,
 392                          '3.6'                       => true,
 393                          '4.0'                       => true,
 394                          '15.0'                      => true,
 395                          '18.0'                      => true,
 396                          '19.0'                      => true,
 397                          '20100101'                  => true,
 398                      ),
 399  
 400                      'versionclasses'                => array(
 401                          'gecko',
 402                      ),
 403                  ),
 404              ),
 405  
 406              // SeaMonkey 2.0; Windows.
 407              array(
 408                  'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1b3pre) Gecko/20081208 SeaMonkey/2.0',
 409                  array(
 410                      'is_gecko'                      => true,
 411                      'check_gecko_version'           => array(
 412                          '1'                         => true,
 413                          '2'                         => true,
 414                          '20030516'                  => true,
 415                          '20051106'                  => true,
 416                          '20051116'                  => true,
 417                          '2006010100'                => true,
 418                      ),
 419  
 420                      'versionclasses'                => array(
 421                          'gecko',
 422                          'gecko19',
 423                      ),
 424                  ),
 425              ),
 426  
 427              // SeaMonkey 2.1; Linux.
 428              array(
 429                  'Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20110609 Firefox/4.0.1 SeaMonkey/2.1',
 430                  array(
 431                      'is_gecko'                      => true,
 432                      'check_gecko_version'           => array(
 433                          '1'                         => true,
 434                          '2'                         => true,
 435                          '20030516'                  => true,
 436                          '20051116'                  => true,
 437                          '2006010100'                => true,
 438                          '20100101'                  => true,
 439                          '3.6'                       => true,
 440                          '4.0'                       => true,
 441                      ),
 442  
 443                      'is_firefox'                    => true,
 444                      'check_firefox_version'         => array(
 445                          '1.5'                       => true,
 446                          '3.0'                       => true,
 447                          '4'                         => true,
 448                      ),
 449  
 450                      'versionclasses'                => array(
 451                          'gecko',
 452                          'gecko20',
 453                      ),
 454                  ),
 455              ),
 456  
 457              // SeaMonkey 2.3; FreeBSD.
 458              array(
 459                  'Mozilla/5.0 (X11; FreeBSD amd64; rv:6.0) Gecko/20110818 Firefox/6.0 SeaMonkey/2.3',
 460                  array(
 461                      'is_gecko'                      => true,
 462                      'check_gecko_version'           => array(
 463                          '1'                         => true,
 464                          '2'                         => true,
 465                          '20030516'                  => true,
 466                          '20051116'                  => true,
 467                          '2006010100'                => true,
 468                          '20100101'                  => true,
 469                          '3.6'                       => true,
 470                          '4.0'                       => true,
 471                      ),
 472  
 473                      'is_firefox'                    => true,
 474                      'check_firefox_version'         => array(
 475                          '1.5'                       => true,
 476                          '3.0'                       => true,
 477                          '4'                         => true,
 478                      ),
 479  
 480                      'versionclasses'                => array(
 481                          'gecko',
 482                      ),
 483                  ),
 484              ),
 485  
 486              // Mac OS X; MS Word 14.
 487              array(
 488                  'Mozilla/5.0 (Macintosh; Intel Mac OS X) Word/14.38.0',
 489                  array(
 490                      'versionclasses'                => array(
 491                      ),
 492  
 493                      'is_msword'                     => true,
 494                  ),
 495              ),
 496  
 497              // Safari 312; Max OS X.
 498              array(
 499                  'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312',
 500                  array(
 501                      'is_safari'                     => true,
 502                      'check_safari_version'          => array(
 503                          '1'                         => true,
 504                          '312'                       => true,
 505                      ),
 506  
 507                      'is_webkit'                     => true,
 508  
 509                      'versionclasses'                => array(
 510                          'safari',
 511                      ),
 512                  ),
 513              ),
 514  
 515              // Safari 412; Max OS X.
 516              array(
 517                  'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412',
 518                  array(
 519                      'is_safari'                     => true,
 520                      'check_safari_version'          => array(
 521                          '1'                         => true,
 522                          '312'                       => true,
 523                      ),
 524  
 525                      'is_webkit'                     => true,
 526  
 527                      'versionclasses'                => array(
 528                          'safari',
 529                      ),
 530                  ),
 531              ),
 532  
 533              // Safari 2.0; Max OS X.
 534              array(
 535                  'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412',
 536                  array(
 537                      'is_safari'                     => true,
 538                      'check_safari_version'          => array(
 539                          '1'                         => true,
 540                          '312'                       => true,
 541                      ),
 542  
 543                      'is_webkit'                     => true,
 544  
 545                      'versionclasses'                => array(
 546                          'safari',
 547                      ),
 548                  ),
 549              ),
 550  
 551              // iOS Safari 528; iPhone.
 552              array(
 553                  'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; cs-cz) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7D11 Safari/528.16',
 554                  array(
 555                      // Note: We do *not* identify mobile Safari as Safari.
 556                      'is_safari_ios'                 => true,
 557                      'is_ios'                        => true,
 558                      'check_safari_ios_version'      => array(
 559                          '527'                       => true,
 560                      ),
 561  
 562                      'is_webkit'                     => true,
 563  
 564                      'versionclasses'                => array(
 565                          'ios'
 566                      ),
 567  
 568                      'devicetype'                    => 'mobile',
 569                 ),
 570              ),
 571  
 572              // Safari; iPhone 6 Plus; iOS 8.1; Build 12B411.
 573              array(
 574                  'Mozilla/5.0 (iPhone; CPU iPhone OS 10_10 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B411 Safari/600.1.4',
 575                  array(
 576                      // Note: We do *not* identify mobile Safari as Safari.
 577                      'is_safari_ios'                 => true,
 578                      'is_ios'                        => true,
 579                      'check_safari_ios_version'      => array(
 580                          '527'                       => true,
 581                          '590'                       => true,
 582                          '600'                       => true,
 583                      ),
 584  
 585                      'is_webkit'                     => true,
 586  
 587                      'versionclasses'                => array(
 588                          'ios',
 589                      ),
 590  
 591                      'devicetype'                    => 'mobile',
 592                 ),
 593              ),
 594  
 595              // iOS Safari 533; iPad.
 596              array(
 597                  'Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5',
 598                  array(
 599                      // Note: We do *not* identify mobile Safari as Safari.
 600                      'is_safari_ios'                 => true,
 601                      'is_ios'                        => true,
 602                      'check_safari_ios_version'      => array(
 603                          '527'                       => true,
 604                      ),
 605  
 606                      'is_webkit'                     => true,
 607  
 608                      'versionclasses'                => array(
 609                          'ios',
 610                      ),
 611  
 612                      'devicetype'                    => 'tablet',
 613                 ),
 614              ),
 615  
 616              // Android WebKit 525; G1 Phone.
 617              'Android WebKit 525; G1 Phone' => array(
 618                  'Mozilla/5.0 (Linux; U; Android 1.1; en-gb; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2 – G1 Phone',
 619                  array(
 620                      'is_webkit_android'             => true,
 621                      'check_webkit_android_version'  => array(
 622                          '525'                       => true,
 623                      ),
 624  
 625                      'is_webkit'                     => true,
 626  
 627                      'versionclasses'                => array(
 628                          'android',
 629                      ),
 630  
 631                      'devicetype'                    => 'mobile',
 632  
 633                      'supports_svg'                  => false,
 634                 ),
 635              ),
 636  
 637              // Android WebKit 530; Nexus.
 638              'Android WebKit 530; Nexus' => array(
 639                  'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17 –Nexus',
 640                  array(
 641                      'is_webkit_android'             => true,
 642                      'check_webkit_android_version'  => array(
 643                          '525'                       => true,
 644                          '527'                       => true,
 645                      ),
 646  
 647                      'is_webkit'                     => true,
 648  
 649                      'versionclasses'                => array(
 650                          'android',
 651                      ),
 652  
 653                      'devicetype'                    => 'mobile',
 654  
 655                      'supports_svg'                  => false,
 656                 ),
 657              ),
 658  
 659              // Android WebKit 537; Samsung GT-9505.
 660              array(
 661                  'Mozilla/5.0 (Linux; Android 4.3; it-it; SAMSUNG GT-I9505/I9505XXUEMJ7 Build/JSS15J) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 Mobile Safari/537.36',
 662                  array(
 663                      'is_webkit_android'             => true,
 664                      'check_webkit_android_version'  => array(
 665                          '525'                       => true,
 666                          '527'                       => true,
 667                      ),
 668  
 669                      'is_webkit'                     => true,
 670  
 671                      'is_chrome'                     => true,
 672                      'check_chrome_version'          => array(
 673                          '7'                         => true,
 674                          '8'                         => true,
 675                          '10'                        => true,
 676                      ),
 677  
 678                      'versionclasses'                => array(
 679                          'chrome',
 680                          'android',
 681                      ),
 682  
 683                      'devicetype'                    => 'mobile',
 684                  ),
 685              ),
 686  
 687              // Android WebKit 537; Nexus 5.
 688              array(
 689                  'Mozilla/5.0 (Linux; Android 5.0; Nexus 5 Build/LPX13D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.102 Mobile Safari/537.36',
 690                  array(
 691                      'is_webkit_android'             => true,
 692                      'check_webkit_android_version'  => array(
 693                          '525'                       => true,
 694                          '527'                       => true,
 695                      ),
 696  
 697                      'is_webkit'                     => true,
 698  
 699                      'is_chrome'                     => true,
 700                      'check_chrome_version'          => array(
 701                          '7'                         => true,
 702                          '8'                         => true,
 703                          '10'                        => true,
 704                      ),
 705  
 706                      'versionclasses'                => array(
 707                          'chrome',
 708                          'android',
 709                      ),
 710  
 711                      'devicetype'                    => 'mobile',
 712                  ),
 713              ),
 714  
 715              // Chrome 8; Mac OS X.
 716              array(
 717                  'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10',
 718                  array(
 719                      'is_chrome'                     => true,
 720                      'check_chrome_version'          => array(
 721                          '7'                         => true,
 722                          '8'                         => true,
 723                      ),
 724  
 725                      'is_webkit'                     => true,
 726  
 727                      'versionclasses'                => array(
 728                          'chrome',
 729                      ),
 730                  ),
 731              ),
 732  
 733              // Chrome 39; Mac OS X.
 734              array(
 735                  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36',
 736                  array(
 737                      'is_chrome'                     => true,
 738                      'check_chrome_version'          => array(
 739                          '7'                         => true,
 740                          '8'                         => true,
 741                          '10'                        => true,
 742                          '39'                        => true,
 743                      ),
 744  
 745                      'is_webkit'                     => true,
 746  
 747                      'versionclasses'                => array(
 748                          'chrome',
 749                      ),
 750                  ),
 751              ),
 752  
 753              // Opera 12.15 (Build 1748); Mac OS X.
 754              array(
 755                  'Opera/9.80 (Macintosh; Intel Mac OS X 10.10.0; Edition MAS) Presto/2.12.388 Version/12.15',
 756                  array(
 757                      'is_opera'                      => true,
 758                      'check_opera_version'           => array(
 759                          '8.0'                       => true,
 760                          '9.0'                       => true,
 761                          '10.0'                      => true,
 762                          '12.15'                     => true,
 763                      ),
 764  
 765                      'versionclasses'                => array(
 766                          'opera',
 767                      ),
 768                 ),
 769              ),
 770  
 771              // Google web crawlers.
 772              array(
 773                  'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
 774                  array(
 775                      'is_web_crawler'                => true,
 776                      'versionclasses'                => array(
 777                      ),
 778                 ),
 779              ),
 780              array(
 781                  'Googlebot/2.1 (+http://www.googlebot.com/bot.html)',
 782                  array(
 783                      'is_web_crawler'                => true,
 784                      'versionclasses'                => array(
 785                      ),
 786                 ),
 787              ),
 788              array(
 789                  'Googlebot-Image/1.0',
 790                  array(
 791                      'is_web_crawler'                => true,
 792                      'versionclasses'                => array(
 793                      ),
 794                 ),
 795              ),
 796  
 797              // Yahoo crawlers.
 798              // See https://help.yahoo.com/kb/slurp-crawling-page-sln22600.html.
 799              array(
 800                  'Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)',
 801                  array(
 802                      'is_web_crawler'                => true,
 803                      'versionclasses'                => array(
 804                      ),
 805                 ),
 806              ),
 807  
 808              // Bing / MSN / AdIdx crawlers.
 809              // See http://www.bing.com/webmaster/help/which-crawlers-does-bing-use-8c184ec0.
 810              array(
 811                  'Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
 812                  array(
 813                      'is_web_crawler'                => true,
 814                      'versionclasses'                => array(
 815                      ),
 816                 ),
 817              ),
 818              array(
 819                  'Mozilla/5.0 (compatible; bingbot/2.0 +http://www.bing.com/bingbot.htm)',
 820                  array(
 821                      'is_web_crawler'                => true,
 822                      'versionclasses'                => array(
 823                      ),
 824                 ),
 825              ),
 826              array(
 827                  'Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
 828                  array(
 829                      'is_web_crawler'                => true,
 830                      'is_webkit'                     => true,
 831                      'is_safari_ios'                 => true,
 832                      'is_ios'                        => true,
 833                      'check_safari_ios_version'      => array(
 834                          '527'                       => true,
 835                      ),
 836  
 837                      'versionclasses'                => array(
 838                          'ios',
 839                      ),
 840  
 841                      'devicetype'                    => 'mobile',
 842                 ),
 843              ),
 844              array(
 845                  'Mozilla/5.0 (Windows Phone 8.1; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 530) like Gecko (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
 846                  array(
 847                      'is_web_crawler'                => true,
 848                      'is_ie'                         => true,
 849                      'check_ie_version'              => array(
 850                          '0'                         => true,
 851                          '5.0'                       => true,
 852                          '5.5'                       => true,
 853                          '6.0'                       => true,
 854                          '7.0'                       => true,
 855                          '8.0'                       => true,
 856                          '9.0'                       => true,
 857                          '10'                        => true,
 858                          '11'                        => true,
 859                      ),
 860                      'versionclasses'                => array(
 861                          'ie',
 862                          'ie11',
 863                      ),
 864                      'devicetype'                    => 'mobile',
 865                 ),
 866              ),
 867  
 868              array(
 869                  'msnbot/2.0b (+http://search.msn.com/msnbot.htm)',
 870                  array(
 871                      'is_web_crawler'                => true,
 872                      'versionclasses'                => array(
 873                      ),
 874                 ),
 875              ),
 876              array(
 877                  'msnbot/2.1',
 878                  array(
 879                      'is_web_crawler'                => true,
 880                      'versionclasses'                => array(
 881                      ),
 882                 ),
 883              ),
 884              array(
 885                  'msnbot-media/1.1 (+http://search.msn.com/msnbot.htm)',
 886                  array(
 887                      'is_web_crawler'                => true,
 888                      'versionclasses'                => array(
 889                      ),
 890                 ),
 891              ),
 892              array(
 893                  'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) BingPreview/1.0b',
 894                  array(
 895                      'is_web_crawler'                => true,
 896                      'is_webkit'                     => true,
 897                      'is_safari'                     => true,
 898                      'check_safari_version'          => array(
 899                          '1'                         => true,
 900                          '312'                       => true,
 901                          '500'                       => true,
 902                      ),
 903  
 904                      'versionclasses'                => array(
 905                          'safari',
 906                      ),
 907                 ),
 908              ),
 909              array(
 910                  'Mozilla/5.0 (Windows Phone 8.1; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 530) like Gecko BingPreview/1.0b',
 911                  array(
 912                      'is_web_crawler'                => true,
 913                      'is_ie'                         => true,
 914                      'check_ie_version'              => array(
 915                          '0'                         => true,
 916                          '5.0'                       => true,
 917                          '5.5'                       => true,
 918                          '6.0'                       => true,
 919                          '7.0'                       => true,
 920                          '8.0'                       => true,
 921                          '9.0'                       => true,
 922                          '10'                        => true,
 923                          '11'                        => true,
 924                      ),
 925                      'versionclasses'                => array(
 926                          'ie',
 927                          'ie11',
 928                      ),
 929                      'devicetype'                    => 'mobile',
 930                 ),
 931              ),
 932  
 933              // Yandex.
 934              // See http://help.yandex.com/search/robots/agent.xml.
 935              array(
 936                  'Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)',
 937                  array(
 938                      'is_web_crawler'                => true,
 939                      'versionclasses'                => array(
 940                      ),
 941                 ),
 942              ),
 943              array(
 944                  'Mozilla/5.0 (compatible; YandexImages/3.0; +http://yandex.com/bots)',
 945                  array(
 946                      'is_web_crawler'                => true,
 947                      'versionclasses'                => array(
 948                      ),
 949                 ),
 950              ),
 951  
 952              // AltaVista.
 953              array(
 954                  'AltaVista V2.0B crawler@evreka.com',
 955                  array(
 956                      'is_web_crawler'                => true,
 957                      'versionclasses'                => array(
 958                      ),
 959                 ),
 960              ),
 961  
 962              // ZoomSpider.
 963              array(
 964                  'ZoomSpider - wrensoft.com [ZSEBOT]',
 965                  array(
 966                      'is_web_crawler'                => true,
 967                      'versionclasses'                => array(
 968                      ),
 969                 ),
 970              ),
 971  
 972              // Baidu.
 973              array(
 974                  'Baiduspider+(+http://www.baidu.com/search/spider_jp.html)',
 975                  array(
 976                      'is_web_crawler'                => true,
 977                      'versionclasses'                => array(
 978                      ),
 979                 ),
 980              ),
 981              array(
 982                  'Baiduspider+(+http://www.baidu.com/search/spider.htm)',
 983                  array(
 984                      'is_web_crawler'                => true,
 985                      'versionclasses'                => array(
 986                      ),
 987                 ),
 988              ),
 989  
 990              // Ask.com.
 991              array(
 992                  'User-Agent: Mozilla/2.0 (compatible; Ask Jeeves/Teoma)',
 993                  array(
 994                      'is_web_crawler'                => true,
 995                      'versionclasses'                => array(
 996                      ),
 997                 ),
 998              ),
 999  
1000              // MoodleBot.
1001              array(
1002                  'User-Agent: MoodleBot/3.8 (+https://moodle.org)',
1003                  array(
1004                      'is_web_crawler'                => true,
1005                      'versionclasses'                => array(
1006                      ),
1007                 ),
1008              ),
1009  
1010              // Macos Desktop app.
1011              array(
1012                  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) moodlemobile/3.6.0 Chrome/69.0.3497.106 Electron/4.0.1 Safari/537.36 MoodleMobile',
1013                  array(
1014                      'is_moodle_app'                => true,
1015                      'is_webkit'                    => true,
1016                      'is_chrome'                    => true,
1017                      'check_chrome_version'         => array(
1018                          '7'                        => true,
1019                          '8'                        => true,
1020                          '10'                       => true,
1021                          '39'                       => true,
1022                      ),
1023                      'versionclasses'               => array(
1024                          'chrome',
1025                      ),
1026                 ),
1027              ),
1028  
1029              // Linux Desktop app.
1030              array(
1031                  'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) moodledesktop/3.6.0 Chrome/69.0.3497.106 Electron/4.0.1 Safari/537.36 MoodleMobile',
1032                  array(
1033                      'is_moodle_app'                => true,
1034                      'is_webkit'                    => true,
1035                      'is_chrome'                    => true,
1036                      'check_chrome_version'         => array(
1037                          '7'                        => true,
1038                          '8'                        => true,
1039                          '10'                       => true,
1040                          '39'                       => true,
1041                      ),
1042                      'versionclasses'               => array(
1043                          'chrome',
1044                      ),
1045                 ),
1046              ),
1047  
1048              // Windows Desktop app.
1049              array(
1050                  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) moodledesktop/3.6.0 Chrome/69.0.3497.106 Electron/4.0.1 Safari/537.36 MoodleMobile',
1051                  array(
1052                      'is_moodle_app'                => true,
1053                      'is_webkit'                    => true,
1054                      'is_chrome'                    => true,
1055                      'check_chrome_version'         => array(
1056                          '7'                        => true,
1057                          '8'                        => true,
1058                          '10'                       => true,
1059                          '39'                       => true,
1060                      ),
1061                      'versionclasses'               => array(
1062                          'chrome',
1063                      ),
1064                 ),
1065              ),
1066  
1067              // Android app.
1068              array(
1069                  'Mozilla/5.0 (Linux; Android 7.1.1; Moto G Play Build/NPIS26.48-43-2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/71.0.3578.99 Mobile Safari/537.36 MoodleMobile',
1070                  array(
1071                      'is_moodle_app'                => true,
1072                      'is_webkit'                    => true,
1073                      'is_webkit_android'            => true,
1074                      'is_chrome'                    => true,
1075                      'check_chrome_version'         => array(
1076                          '7'                        => true,
1077                          '8'                        => true,
1078                          '10'                       => true,
1079                          '39'                       => true,
1080                      ),
1081                      'devicetype'                   => 'mobile',
1082                      'check_webkit_android_version' => array(
1083                          '525'                       => true,
1084                          '527'                       => true,
1085                      ),
1086                      'versionclasses'               => array(
1087                          'android',
1088                          'chrome'
1089                      ),
1090                 ),
1091              ),
1092  
1093              // Android app, user agent lower case.
1094              array(
1095                  'Mozilla/5.0 (Linux; Android 7.1.1; Moto G Play Build/NPIS26.48-43-2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/71.0.3578.99 Mobile Safari/537.36 moodlemobile',
1096                  array(
1097                      'is_moodle_app'                => true,
1098                      'is_webkit'                    => true,
1099                      'is_webkit_android'            => true,
1100                      'is_chrome'                    => true,
1101                      'check_chrome_version'         => array(
1102                          '7'                        => true,
1103                          '8'                        => true,
1104                          '10'                       => true,
1105                          '39'                       => true,
1106                      ),
1107                      'devicetype'                   => 'mobile',
1108                      'check_webkit_android_version' => array(
1109                          '525'                       => true,
1110                          '527'                       => true,
1111                      ),
1112                      'versionclasses'               => array(
1113                          'android',
1114                          'chrome'
1115                      ),
1116                 ),
1117              ),
1118  
1119              // iOS (iPhone) app.
1120              array(
1121                  'Mozilla/5.0 (iPhone; CPU OS 13_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 MoodleMobile',
1122                  array(
1123                      'is_moodle_app'                => true,
1124                      'is_ios'                       => true,
1125                      'is_webkit'                    => true,
1126                      'devicetype'                   => 'mobile',
1127                      'versionclasses'               => array(
1128                      ),
1129                 ),
1130              ),
1131  
1132              // iOS (iPad) app.
1133              array(
1134                  'Mozilla/5.0 (iPad; CPU OS 12_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16D39 MoodleMobile',
1135                  array(
1136                      'is_moodle_app'                => true,
1137                      'is_ios'                       => true,
1138                      'is_webkit'                    => true,
1139                      'devicetype'                   => 'tablet',
1140                      'versionclasses'               => array(
1141                      ),
1142                 ),
1143              ),
1144          );
1145      }
1146  
1147      /**
1148       * Test instance generation.
1149       */
1150      public function test_instance() {
1151          $this->assertInstanceOf('core_useragent', core_useragent::instance());
1152          $this->assertInstanceOf('core_useragent', core_useragent::instance(true));
1153      }
1154  
1155      /**
1156       * @dataProvider user_agents_providers
1157       */
1158      public function test_useragent_edge($useragent, $tests) {
1159          // Setup the core_useragent instance.
1160          core_useragent::instance(true, $useragent);
1161  
1162          // Edge Tests.
1163          if (isset($tests['is_edge']) && $tests['is_edge']) {
1164              $this->assertTrue(core_useragent::is_edge());
1165          } else {
1166              $this->assertFalse(core_useragent::is_edge());
1167          }
1168  
1169          $versions = array(
1170              // New versions of should be added here.
1171              '12'   => false,
1172          );
1173  
1174          if (isset($tests['check_edge_version'])) {
1175              // The test provider has overwritten some of the above checks.
1176              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1177              $versions = $tests['check_edge_version'] + $versions;
1178          }
1179  
1180          foreach ($versions as $version => $result) {
1181              $this->assertEquals($result, core_useragent::check_edge_version($version),
1182                  "Version incorrectly determined for Edge version '{$version}'");
1183          }
1184      }
1185  
1186      /**
1187       * @dataProvider user_agents_providers
1188       */
1189      public function test_useragent_ie($useragent, $tests) {
1190          // Setup the core_useragent instance.
1191          core_useragent::instance(true, $useragent);
1192  
1193          // IE Tests.
1194          if (isset($tests['is_ie']) && $tests['is_ie']) {
1195              $this->assertTrue(core_useragent::is_ie());
1196          } else {
1197              $this->assertFalse(core_useragent::is_ie());
1198          }
1199  
1200          $versions = array(
1201              // New versions of should be added here.
1202              '0'    => false,
1203              '5.0'  => false,
1204              '5.5'  => false,
1205              '6.0'  => false,
1206              '7.0'  => false,
1207              '8.0'  => false,
1208              '9.0'  => false,
1209              '10'   => false,
1210              '11'   => false,
1211              '12'   => false,
1212              '13'   => false,
1213              '14'   => false,
1214          );
1215  
1216          if (isset($tests['check_ie_version'])) {
1217              // The test provider has overwritten some of the above checks.
1218              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1219              $versions = $tests['check_ie_version'] + $versions;
1220          }
1221  
1222          foreach ($versions as $version => $result) {
1223              $this->assertEquals($result, core_useragent::check_ie_version($version),
1224                  "Version incorrectly determined for IE version '{$version}'");
1225          }
1226  
1227          // IE Compatibility mode.
1228          if (isset($tests['iecompatibility']) && $tests['iecompatibility']) {
1229              $this->assertTrue(core_useragent::check_ie_compatibility_view(), "IE Compability false negative");
1230          } else {
1231              $this->assertFalse(core_useragent::check_ie_compatibility_view(), "IE Compability false positive");
1232          }
1233  
1234      }
1235  
1236      /**
1237       * @dataProvider user_agents_providers
1238       */
1239      public function test_useragent_msword($useragent, $tests) {
1240          // Setup the core_useragent instance.
1241          core_useragent::instance(true, $useragent);
1242  
1243          // MSWord Tests.
1244          if (isset($tests['is_msword']) && $tests['is_msword']) {
1245              $this->assertTrue(core_useragent::is_msword());
1246          } else {
1247              $this->assertFalse(core_useragent::is_msword());
1248          }
1249      }
1250  
1251      /**
1252       * @dataProvider user_agents_providers
1253       */
1254      public function test_useragent_supports($useragent, $tests) {
1255          // Setup the core_useragent instance.
1256          core_useragent::instance(true, $useragent);
1257  
1258          // Supports SVG.
1259          if (!isset($tests['supports_svg']) || $tests['supports_svg']) {
1260              $this->assertTrue(core_useragent::supports_svg(),
1261                  "SVG Support was not reported (and should have been)");
1262          } else {
1263              $this->assertFalse(core_useragent::supports_svg(),
1264                  "SVG Support was reported (and should not have been)");
1265          }
1266  
1267          // Supports JSON ContentType.
1268          if (!isset($tests['supports_json_contenttype']) || $tests['supports_json_contenttype']) {
1269              $this->assertTrue(core_useragent::supports_json_contenttype(),
1270                  "JSON ContentType Support was not reported (and should have been)");
1271          } else {
1272              $this->assertFalse(core_useragent::supports_json_contenttype(),
1273                  "JSON ContentType Support was reported (and should not have been)");
1274          }
1275      }
1276  
1277      /**
1278       * @dataProvider user_agents_providers
1279       */
1280      public function test_useragent_webkit($useragent, $tests) {
1281          // Setup the core_useragent instance.
1282          core_useragent::instance(true, $useragent);
1283  
1284          if (isset($tests['is_webkit']) && $tests['is_webkit']) {
1285              $this->assertTrue(core_useragent::is_webkit(),
1286                  "Browser was not identified as a webkit browser");
1287              $this->assertTrue(core_useragent::check_webkit_version());
1288          } else {
1289              $this->assertFalse(core_useragent::is_webkit(),
1290                  "Browser was incorrectly identified as a webkit browser");
1291              $this->assertFalse(core_useragent::check_webkit_version());
1292          }
1293  
1294          $versions = array(
1295              // New versions should be added here.
1296          );
1297  
1298          if (isset($tests['check_webkit_version'])) {
1299              // The test provider has overwritten some of the above checks.
1300              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1301              $versions = $tests['check_webkit_version'] + $versions;
1302          }
1303  
1304          foreach ($versions as $version => $result) {
1305              $this->assertEquals($result, core_useragent::check_webkit_version($version),
1306                  "Version incorrectly determined for Webkit version '{$version}'");
1307          }
1308      }
1309  
1310      /**
1311       * @dataProvider user_agents_providers
1312       */
1313      public function test_useragent_webkit_android($useragent, $tests) {
1314          // Setup the core_useragent instance.
1315          core_useragent::instance(true, $useragent);
1316  
1317          if (isset($tests['is_webkit_android']) && $tests['is_webkit_android']) {
1318              $this->assertTrue(core_useragent::is_webkit_android(),
1319                  "Browser was not identified as an Android webkit browser");
1320              $this->assertTrue(core_useragent::check_webkit_android_version());
1321          } else {
1322              $this->assertFalse(core_useragent::is_webkit_android(),
1323                  "Browser was incorrectly identified as an Android webkit browser");
1324              $this->assertFalse(core_useragent::check_webkit_android_version());
1325          }
1326  
1327          $versions = array(
1328              // New versions should be added here.
1329              '525'       => false,
1330              '527'       => false,
1331              '590'       => false,
1332          );
1333  
1334          if (isset($tests['check_webkit_android_version'])) {
1335              // The test provider has overwritten some of the above checks.
1336              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1337              $versions = $tests['check_webkit_android_version'] + $versions;
1338          }
1339  
1340          foreach ($versions as $version => $result) {
1341              $this->assertEquals($result, core_useragent::check_webkit_android_version($version),
1342                  "Version incorrectly determined for Android webkit version '{$version}'");
1343          }
1344      }
1345  
1346      /**
1347       * @dataProvider user_agents_providers
1348       */
1349      public function test_useragent_chrome($useragent, $tests) {
1350          // Setup the core_useragent instance.
1351          core_useragent::instance(true, $useragent);
1352  
1353          if (isset($tests['is_chrome']) && $tests['is_chrome']) {
1354              $this->assertTrue(core_useragent::is_chrome(),
1355                  "Browser was not identified as a chrome browser");
1356              $this->assertTrue(core_useragent::check_chrome_version());
1357          } else {
1358              $this->assertFalse(core_useragent::is_chrome(),
1359                  "Browser was incorrectly identified as a chrome browser");
1360              $this->assertFalse(core_useragent::check_chrome_version());
1361          }
1362  
1363          $versions = array(
1364              // New versions should be added here.
1365              '7'         => false,
1366              '8'         => false,
1367              '10'        => false,
1368              '39'        => false,
1369          );
1370  
1371          if (isset($tests['check_chrome_version'])) {
1372              // The test provider has overwritten some of the above checks.
1373              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1374              $versions = $tests['check_chrome_version'] + $versions;
1375          }
1376  
1377          foreach ($versions as $version => $result) {
1378              $this->assertEquals($result, core_useragent::check_chrome_version($version),
1379                  "Version incorrectly determined for Chrome version '{$version}'");
1380          }
1381      }
1382  
1383      /**
1384       * @dataProvider user_agents_providers
1385       */
1386      public function test_useragent_safari($useragent, $tests) {
1387          // Setup the core_useragent instance.
1388          core_useragent::instance(true, $useragent);
1389  
1390          if (isset($tests['is_safari']) && $tests['is_safari']) {
1391              $this->assertTrue(core_useragent::is_safari(),
1392                  "Browser was not identified as a safari browser");
1393              $this->assertTrue(core_useragent::check_safari_version());
1394          } else {
1395              $this->assertFalse(core_useragent::is_safari(),
1396                  "Browser was incorrectly identified as a safari browser");
1397              $this->assertFalse(core_useragent::check_safari_version());
1398          }
1399  
1400          // Check Safari (generic).
1401          $versions = array(
1402              // New versions should be added here.
1403              '1'         => false,
1404              '312'       => false,
1405              '500'       => false,
1406          );
1407  
1408          if (isset($tests['check_safari_version'])) {
1409              // The test provider has overwritten some of the above checks.
1410              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1411              $versions = $tests['check_safari_version'] + $versions;
1412          }
1413  
1414          foreach ($versions as $version => $result) {
1415              $this->assertEquals($result, core_useragent::check_safari_version($version),
1416                  "Version incorrectly determined for Safari (generic) version '{$version}'");
1417          }
1418      }
1419  
1420      /**
1421       * @dataProvider user_agents_providers
1422       */
1423      public function test_useragent_ios_safari($useragent, $tests) {
1424          // Setup the core_useragent instance.
1425          core_useragent::instance(true, $useragent);
1426  
1427          if (isset($tests['is_safari_ios']) && $tests['is_safari_ios']) {
1428              $this->assertTrue(core_useragent::is_safari_ios(),
1429                  "Browser was not identified as an iOS safari browser");
1430              $this->assertTrue(core_useragent::check_safari_ios_version());
1431          } else {
1432              $this->assertFalse(core_useragent::is_safari_ios(),
1433                  "Browser was incorrectly identified as an iOS safari browser");
1434              $this->assertFalse(core_useragent::check_safari_ios_version());
1435          }
1436  
1437          // Check iOS Safari.
1438          $versions = array(
1439              // New versions should be added here.
1440              '527'       => false,
1441              '590'       => false,
1442              '600'       => false,
1443          );
1444  
1445          if (isset($tests['check_safari_ios_version'])) {
1446              // The test provider has overwritten some of the above checks.
1447              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1448              $versions = $tests['check_safari_ios_version'] + $versions;
1449          }
1450  
1451          foreach ($versions as $version => $result) {
1452              $this->assertEquals($result, core_useragent::check_safari_ios_version($version),
1453                  "Version incorrectly determined for iOS Safari version '{$version}'");
1454          }
1455      }
1456  
1457      /**
1458       * @dataProvider user_agents_providers
1459       */
1460      public function test_useragent_ios($useragent, $tests) {
1461          // Setup the core_useragent instance.
1462          core_useragent::instance(true, $useragent);
1463  
1464          if (isset($tests['is_ios']) && $tests['is_ios']) {
1465              $this->assertTrue(core_useragent::is_ios(),
1466                  "Browser was not identified as an iOS device browser");
1467              // The iOS app is not Safari based.
1468              if (!isset($tests['is_moodle_app']) || !$tests['is_moodle_app']) {
1469                  $this->assertTrue(core_useragent::check_safari_ios_version());
1470              }
1471          } else {
1472              $this->assertFalse(core_useragent::is_ios(),
1473                  "Browser was incorrectly identified as an iOS device browser");
1474              $this->assertFalse(core_useragent::check_safari_ios_version());
1475          }
1476      }
1477  
1478      /**
1479       * @dataProvider user_agents_providers
1480       */
1481      public function test_useragent_gecko($useragent, $tests) {
1482          // Setup the core_useragent instance.
1483          core_useragent::instance(true, $useragent);
1484  
1485          if (isset($tests['is_gecko']) && $tests['is_gecko']) {
1486              $this->assertTrue(core_useragent::is_gecko(),
1487                  "Browser was not identified as a gecko browser");
1488              $this->assertTrue(core_useragent::check_gecko_version());
1489          } else {
1490              $this->assertFalse(core_useragent::is_gecko(),
1491                  "Browser was incorrectly identified as a gecko browser");
1492              $this->assertFalse(core_useragent::check_gecko_version());
1493          }
1494  
1495          $versions = array(
1496              // New versions should be added here.
1497              '1'             => false,
1498              '2'             => false,
1499              '3.6'           => false,
1500              '4.0'           => false,
1501              '20030516'      => false,
1502              '20051116'      => false,
1503              '2006010100'    => false,
1504              '20100101'      => false,
1505              '15.0'          => false,
1506              '18.0'          => false,
1507              '19.0'          => false,
1508          );
1509  
1510          if (isset($tests['check_gecko_version'])) {
1511              // The test provider has overwritten some of the above checks.
1512              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1513              $versions = $tests['check_gecko_version'] + $versions;
1514          }
1515  
1516          foreach ($versions as $version => $result) {
1517              $this->assertEquals($result, core_useragent::check_gecko_version($version),
1518                  "Version incorrectly determined for Gecko version '{$version}'");
1519          }
1520      }
1521  
1522      /**
1523       * @dataProvider user_agents_providers
1524       */
1525      public function test_useragent_firefox($useragent, $tests) {
1526          // Setup the core_useragent instance.
1527          core_useragent::instance(true, $useragent);
1528  
1529          if (isset($tests['is_firefox']) && $tests['is_firefox']) {
1530              $this->assertTrue(core_useragent::is_firefox(),
1531                  "Browser was not identified as a firefox browser");
1532              $this->assertTrue(core_useragent::check_firefox_version());
1533          } else {
1534              $this->assertFalse(core_useragent::is_firefox(),
1535                  "Browser was incorrectly identified as a firefox browser");
1536              $this->assertFalse(core_useragent::check_firefox_version());
1537          }
1538  
1539          $versions = array(
1540              // New versions should be added here.
1541              '1.5'       => false,
1542              '3.0'       => false,
1543              '4'         => false,
1544              '10'        => false,
1545              '15'        => false,
1546              '18'        => false,
1547              '19'        => false,
1548              '33'        => false,
1549          );
1550  
1551          if (isset($tests['check_firefox_version'])) {
1552              // The test provider has overwritten some of the above checks.
1553              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1554              $versions = $tests['check_firefox_version'] + $versions;
1555          }
1556  
1557          foreach ($versions as $version => $result) {
1558              $this->assertEquals($result, core_useragent::check_firefox_version($version),
1559                  "Version incorrectly determined for Firefox version '{$version}'");
1560          }
1561      }
1562  
1563      /**
1564       * @dataProvider user_agents_providers
1565       */
1566      public function test_useragent_opera($useragent, $tests) {
1567          // Setup the core_useragent instance.
1568          core_useragent::instance(true, $useragent);
1569  
1570          if (isset($tests['is_opera']) && $tests['is_opera']) {
1571              $this->assertTrue(core_useragent::is_opera(),
1572                  "Browser was not identified as a opera browser");
1573              $this->assertTrue(core_useragent::check_opera_version());
1574          } else {
1575              $this->assertFalse(core_useragent::is_opera(),
1576                  "Browser was incorrectly identified as a opera browser");
1577              $this->assertFalse(core_useragent::check_opera_version());
1578          }
1579  
1580          $versions = array(
1581              // New versions should be added here.
1582              '8.0'       => false,
1583              '9.0'       => false,
1584              '10.0'      => false,
1585              '12.15'     => false,
1586          );
1587  
1588          if (isset($tests['check_opera_version'])) {
1589              // The test provider has overwritten some of the above checks.
1590              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1591              $versions = $tests['check_opera_version'] + $versions;
1592          }
1593  
1594          foreach ($versions as $version => $result) {
1595              $this->assertEquals($result, core_useragent::check_opera_version($version),
1596                  "Version incorrectly determined for Opera version '{$version}'");
1597          }
1598      }
1599  
1600      /**
1601       * @dataProvider user_agents_providers
1602       */
1603      public function test_get_device_type($useragent, $tests) {
1604          // Setup the core_useragent instance.
1605          core_useragent::instance(true, $useragent);
1606  
1607          $expected = 'default';
1608          if (isset($tests['devicetype'])) {
1609              $expected = $tests['devicetype'];
1610          }
1611  
1612          $this->assertEquals($expected, core_useragent::get_device_type(),
1613              "Device Type was not correctly identified");
1614      }
1615  
1616      /**
1617       * @dataProvider user_agents_providers
1618       */
1619      public function test_get_browser_version_classes($useragent, $tests) {
1620          // Setup the core_useragent instance.
1621          core_useragent::instance(true, $useragent);
1622  
1623          $actual = core_useragent::get_browser_version_classes();
1624          foreach ($tests['versionclasses'] as $expectedclass) {
1625              $this->assertContains($expectedclass, $actual);
1626          }
1627          $this->assertCount(count($tests['versionclasses']), $actual);
1628      }
1629  
1630      /**
1631       * @dataProvider user_agents_providers
1632       */
1633      public function test_useragent_web_crawler($useragent, $tests) {
1634          // Setup the core_useragent instance.
1635          core_useragent::instance(true, $useragent);
1636  
1637          $expectation = isset($tests['is_web_crawler']) ? $tests['is_web_crawler'] : false;
1638          $this->assertSame($expectation, core_useragent::is_web_crawler());
1639      }
1640  
1641      /**
1642       * @dataProvider user_agents_providers
1643       */
1644      public function test_useragent_moodle_app($useragent, $tests) {
1645          // Setup the core_useragent instance.
1646          core_useragent::instance(true, $useragent);
1647  
1648          $expectation = isset($tests['is_moodle_app']) ? $tests['is_moodle_app'] : false;
1649          $this->assertSame($expectation, core_useragent::is_moodle_app());
1650      }
1651  }