jenkins-bot has submitted this change and it was merged.

Change subject: Extract extra device detection from MobileContext
......................................................................


Extract extra device detection from MobileContext

... and break it into discrete units.

Additional device detection logic exists in MobileContext#getAMF and
whether the request is sent from a mobile or tablet device: in the case
of #getAMF, environment variables set by the Apache Mobile Filter
module; in the case of #getDevice, a configurable request header.

Patrick Reilly's IDeviceDetector interface is a good start for a
boundary for all device detection code. However, in order to support the
cases above, it needs to be extended to accept more application state.

Changes:
* Create MobileFrontend\Devices\DeviceDetector from IDeviceDetector.
* Create DeviceProperties, a simple DTO, from IDeviceProperties.
* Add MobileFrontend\Devices\AMFDeviceDetector and
  CustomHeaderDeviceDetector, which cover the above cases.
* Create UADeviceDetector from IDeviceProperties, which covers the
  existing case

Bug: T143891
Change-Id: I8f5df2b8af407c2ec6763f2c2d7d99d3342065c1
---
M extension.json
A includes/devices/AMFDeviceDetector.php
A includes/devices/CustomHeaderDeviceDetector.php
A includes/devices/DeviceDetector.php
A includes/devices/DeviceProperties.php
A includes/devices/UADeviceDetector.php
A tests/phpunit/devices/AMFDeviceDetectorTest.php
A tests/phpunit/devices/CustomHeaderDeviceDetectorTest.php
A tests/phpunit/devices/UADeviceDetectorTest.php
9 files changed, 675 insertions(+), 1 deletion(-)

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



diff --git a/extension.json b/extension.json
index 1eb0a0a..0bd1aad 100644
--- a/extension.json
+++ b/extension.json
@@ -91,7 +91,12 @@
                "SkinMinerva": "includes/skins/SkinMinerva.php",
                "SkinMinervaBeta": "includes/skins/SkinMinervaBeta.php",
                "MobileFrontend\\MenuBuilder": "includes/MenuBuilder.php",
-               "MobileFrontend\\MenuEntry": "includes/MenuBuilder.php"
+               "MobileFrontend\\MenuEntry": "includes/MenuBuilder.php",
+               "MobileFrontend\\Devices\\DeviceDetector": 
"includes/devices/DeviceDetector.php",
+               "MobileFrontend\\Devices\\DeviceProperties": 
"includes/devices/DeviceProperties.php",
+               "MobileFrontend\\Devices\\AMFDeviceDetector": 
"includes/devices/AMFDeviceDetector.php",
+               "MobileFrontend\\Devices\\CustomHeaderDeviceDetector": 
"includes/devices/CustomHeaderDeviceDetector.php",
+               "MobileFrontend\\Devices\\UADeviceDetector": 
"includes/devices/UADeviceDetector.php"
        },
        "ResourceModules": {
                "skins.minerva.base.reset": {
diff --git a/includes/devices/AMFDeviceDetector.php 
b/includes/devices/AMFDeviceDetector.php
new file mode 100644
index 0000000..4c5c822
--- /dev/null
+++ b/includes/devices/AMFDeviceDetector.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace MobileFrontend\Devices;
+
+use WebRequest;
+
+/**
+ * Detect mobile and tablet devices using environment variables set by the
+ * Apache Mobile Filter (AMF) module.
+ *
+ * @link http://wiki.apachemobilefilter.org/index.php/Main_Page
+ */
+class AMFDeviceDetector implements DeviceDetector {
+       public function detectDeviceProperties( WebRequest $request, array 
$server ) {
+               $hasIsMobile = isset( $server['AMF_DEVICE_IS_MOBILE'] );
+               $hasIsTablet = isset( $server['AMF_DEVICE_IS_TABLET'] );
+
+               if ( !$hasIsMobile && !$hasIsTablet ) {
+                       return null;
+               }
+
+               $isMobileDevice = $hasIsMobile
+                       && $server['AMF_DEVICE_IS_MOBILE'] === 'true';
+
+               $isTabletDevice = $hasIsTablet
+                       && $server['AMF_DEVICE_IS_TABLET'] === 'true';
+
+               return new DeviceProperties( $isMobileDevice, $isTabletDevice );
+       }
+}
diff --git a/includes/devices/CustomHeaderDeviceDetector.php 
b/includes/devices/CustomHeaderDeviceDetector.php
new file mode 100644
index 0000000..403c5cc
--- /dev/null
+++ b/includes/devices/CustomHeaderDeviceDetector.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace MobileFrontend\Devices;
+
+use Config;
+use WebRequest;
+
+/**
+ * Detects mobile devices by testing whether a custom request header is 
present.
+ *
+ * @note See README.md for more detail on `$wgMFMobileHeader`.
+ */
+class CustomHeaderDeviceDetector implements DeviceDetector {
+
+       /**
+        * The name of the custom request header.
+        *
+        * @var string
+        */
+       private $customHeaderName;
+
+       /**
+        * @param Config $config The global config. Currently this can be any 
instance
+        *  of `GlobalVarConfig`.
+        *
+        * @TODO In future, however, this should probably be a 
MobileFrontend-specific
+        * instance. `GlobalVarConfig#__construct` accepts a custom prefix to 
avoid
+        * repeating prefixes in `#get` calls, e.g.
+        *
+        * ```
+        * $config = new GlobalVarConfig();
+        * $mobileFrontendConfig = new GlobalVarConfig( 'wgMF' );
+        *
+        * assert(
+        *   $config->get( 'MFMobileHeader' )
+        *   === $mobileFrontendConfig->get( 'MobileHeader' )
+        * );
+        * ```
+        */
+       public function __construct( Config $config ) {
+               $this->customHeaderName = $config->get( 'MFMobileHeader' );
+       }
+
+       public function detectDeviceProperties( WebRequest $request, array 
$server ) {
+               if (
+                       $this->customHeaderName
+                       && $request->getHeader( $this->customHeaderName ) !== 
false
+               ) {
+                       return new DeviceProperties( true, false );
+               }
+       }
+}
diff --git a/includes/devices/DeviceDetector.php 
b/includes/devices/DeviceDetector.php
new file mode 100644
index 0000000..5ef72b4
--- /dev/null
+++ b/includes/devices/DeviceDetector.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * Copyright (c) 2011 Patrick Reilly
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+namespace MobileFrontend\Devices;
+
+use WebRequest;
+
+/**
+ * Detects the properties of the device that's making the request on behalf of
+ * the user.
+ *
+ * @see DeviceProperties
+ */
+interface DeviceDetector {
+
+       /**
+        * Report, if possible, the properties of the device that's being used 
to
+        * access the wiki.
+        *
+        * Because `WebRequest` doesn't currently provide read-only access to 
the
+        * `$_SERVER` superglobal within its API, it's expected to be passed as
+        * additional context.
+        *
+        * @param WebRequest $request
+        * @param array $server Per the above, the `$_SERVER` superglobal
+        * @return {DeviceProperties|null}
+        */
+       function detectDeviceProperties( WebRequest $request, array $server );
+}
diff --git a/includes/devices/DeviceProperties.php 
b/includes/devices/DeviceProperties.php
new file mode 100644
index 0000000..62cddc3
--- /dev/null
+++ b/includes/devices/DeviceProperties.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * Copyright (c) 2011 Patrick Reilly
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+namespace MobileFrontend\Devices;
+
+/**
+ * A Data Transfer Object whose properties are whether the device making the
+ * request is a mobile device, a tablet device, or neither.
+ */
+class DeviceProperties {
+       private $isMobileDevice;
+       private $isTabletDevice;
+
+       /**
+        * @param bool $isMobileDevice
+        * @param bool $isTabletDevice
+        */
+       public function __construct( $isMobileDevice, $isTabletDevice ) {
+               $this->isMobileDevice = $isMobileDevice;
+               $this->isTabletDevice = $isTabletDevice;
+       }
+
+       /**
+        * Is the device a mobile device?
+        *
+        * @return bool
+        */
+       public function isMobileDevice() {
+               return $this->isMobileDevice;
+       }
+
+       /**
+        * Is the device a tablet device?
+        *
+        * @return bool
+        */
+       public function isTabletDevice() {
+               return $this->isTabletDevice;
+       }
+}
diff --git a/includes/devices/UADeviceDetector.php 
b/includes/devices/UADeviceDetector.php
new file mode 100644
index 0000000..253206e
--- /dev/null
+++ b/includes/devices/UADeviceDetector.php
@@ -0,0 +1,139 @@
+<?php
+
+/**
+ * Copyright (c) 2011 Patrick Reilly
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+namespace MobileFrontend\Devices;
+
+use WebRequest;
+
+/**
+ * Detect mobile and tablet devices by testing whether the User-Agent request
+ * header matches a list of regular expressions.
+ */
+class UADeviceDetector implements DeviceDetector {
+       public function detectDeviceProperties( WebRequest $request, array 
$server ) {
+               $userAgent = $request->getHeader( 'User-Agent' );
+
+               return new DeviceProperties(
+                       $this->detectMobileDevice( $userAgent ),
+                       $this->detectTabletDevice( $userAgent )
+               );
+       }
+
+       /**
+        * Tests whether the UA is known to be sent on behalf of users using a 
mobile
+        * device.
+        *
+        * @author Patrick Reilly
+        *
+        * @param $userAgent
+        * @return bool
+        */
+       private function detectMobileDevice( $userAgent ) {
+               $patterns = [
+                       'mobi',
+                       '240x240',
+                       '240x320',
+                       '320x320',
+                       'alcatel',
+                       'android',
+                       'audiovox',
+                       'bada',
+                       'benq',
+                       'blackberry',
+                       'cdm-',
+                       'compal-',
+                       'docomo',
+                       'ericsson',
+                       'hiptop',
+                       'htc[-_]',
+                       'huawei',
+                       'ipod',
+                       'kddi-',
+                       'kindle',
+                       'meego',
+                       'midp',
+                       'mitsu',
+                       'mmp\/',
+                       'mot-',
+                       'motor',
+                       'ngm_',
+                       'nintendo',
+                       'opera.m',
+                       'palm',
+                       'panasonic',
+                       'philips',
+                       'phone',
+                       'playstation',
+                       'portalmmm',
+                       'sagem-',
+                       'samsung',
+                       'sanyo',
+                       'sec-',
+                       'sendo',
+                       'sharp',
+                       'silk',
+                       'softbank',
+                       'symbian',
+                       'teleca',
+                       'up.browser',
+                       'webos',
+               ];
+               $patternsStart = [
+                       'lg-',
+                       'sie-',
+                       'nec-',
+                       'lge-',
+                       'sgh-',
+                       'pg-',
+               ];
+               $regex = '/^(' . implode( '|', $patternsStart ) . ')|(' . 
implode( '|', $patterns ) . ')/i';
+               $exceptionRegex = '/SMART-TV.*SamsungBrowser/';
+
+               return preg_match( $regex, $userAgent )
+                       && !preg_match( $exceptionRegex, $userAgent );
+       }
+
+       /**
+        * Tests whether the UA is known to be sent on behalf of users using a 
tablet
+        * device.
+        *
+        * @author Patrick Reilly
+        *
+        * @param $userAgent
+        * @return bool
+        */
+       private function detectTabletDevice( $userAgent ) {
+
+               // The only way to distinguish Android browsers on tablet from 
Android
+               // browsers on mobile is that Android browsers on tablet 
usually don't
+               // include the word "mobile". We look for "mobi" instead of 
"mobile" due to
+               // Opera Mobile. Note that this test fails to detect some 
obscure tablets
+               // such as older Xoom tablets and Portablet tablets. See
+               // http://stackoverflow.com/questions/5341637 for more detail.
+               if ( preg_match( '/Android/i', $userAgent ) ) {
+                       return !preg_match( '/mobi/i', $userAgent );
+               }
+
+               return (bool)preg_match( '/(iPad|Tablet|PlayBook|Wii|Silk)/i', 
$userAgent );
+       }
+}
diff --git a/tests/phpunit/devices/AMFDeviceDetectorTest.php 
b/tests/phpunit/devices/AMFDeviceDetectorTest.php
new file mode 100644
index 0000000..b2ef95c
--- /dev/null
+++ b/tests/phpunit/devices/AMFDeviceDetectorTest.php
@@ -0,0 +1,81 @@
+<?php
+
+namespace Tests\MobileFrontend\Devices;
+
+use MediaWikiTestCase;
+use WebRequest;
+use MobileFrontend\Devices\AMFDeviceDetector;
+
+class AMFDeviceDetectorTest extends MediaWikiTestCase {
+
+       /**
+        * @var WebRequest
+        */
+       private $request;
+
+       /**
+        * @var AMFDeviceDetector
+        */
+       private $detector;
+
+       protected function setUp() {
+               parent::setUp();
+
+               $this->request = new WebRequest();
+               $this->detector = new AMFDeviceDetector();
+       }
+
+       /**
+        * @dataProvider provideIsMobileDevice
+        */
+       public function testIsMobileDevice( $server, $expectedIsMobileDevice ) {
+               $isMobileDevice =
+                       $this->detector->detectDeviceProperties( 
$this->request, $server )
+                               ->isMobileDevice();
+
+               $this->assertEquals( $expectedIsMobileDevice, $isMobileDevice );
+       }
+
+       public static function provideIsMobileDevice() {
+               return [
+                       [
+                               [ 'AMF_DEVICE_IS_MOBILE' => 'true' ],
+                               true,
+                       ],
+                       [
+                               [ 'AMF_DEVICE_IS_MOBILE' => 'false' ],
+                               false,
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideIsTabletDevice
+        */
+       public function testIsTabletDevice( $server, $expectedIsTabletDevice ) {
+               $isTabletDevice =
+                       $this->detector->detectDeviceProperties( 
$this->request, $server )
+                               ->isTabletDevice();
+
+               $this->assertEquals( $expectedIsTabletDevice, $isTabletDevice );
+       }
+
+       public static function provideIsTabletDevice() {
+               return [
+                       [
+                               [ 'AMF_DEVICE_IS_TABLET' => 'true' ],
+                               true,
+                       ],
+                       [
+                               [ 'AMF_DEVICE_IS_TABLET' => 'false' ],
+                               false,
+                       ],
+               ];
+       }
+
+       public function test_it_should_handle_no_AMF_environment_variables() {
+               $this->assertNull(
+                       $this->detector->detectDeviceProperties( 
$this->request, [] )
+               );
+       }
+}
diff --git a/tests/phpunit/devices/CustomHeaderDeviceDetectorTest.php 
b/tests/phpunit/devices/CustomHeaderDeviceDetectorTest.php
new file mode 100644
index 0000000..0bb942f
--- /dev/null
+++ b/tests/phpunit/devices/CustomHeaderDeviceDetectorTest.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Tests\MobileFrontend\Devices;
+
+use MediaWikiTestCase;
+use FauxRequest;
+use HashConfig;
+use MobileFrontend\Devices\CustomHeaderDeviceDetector;
+
+class CustomHeaderDeviceDetectorTest extends MediaWikiTestCase {
+
+       /**
+        * @var GlobalVarConfig
+        */
+       private $config;
+
+       /**
+        * @var UADeviceDetector
+        */
+       private $detector;
+
+       /**
+        * @var FauxRequest
+        */
+       private $request;
+
+       protected function setUp() {
+               parent::setUp();
+
+               $config = new HashConfig();
+               $config->set( 'MFMobileHeader', 'FooHeader' );
+
+               $this->detector = new CustomHeaderDeviceDetector( $config );
+               $this->request = new FauxRequest();
+       }
+
+       public function test_is_null_when_custom_header_isnt_present() {
+               $this->assertNull(
+                       $this->detector->detectDeviceProperties( 
$this->request, [] )
+               );
+       }
+
+       public function test_isMobile_when_mobile_header_is_present() {
+               $this->request->setHeader( 'FooHeader',  '' );
+
+               $properties = $this->detector->detectDeviceProperties( 
$this->request, [] );
+
+               $this->assertTrue( $properties->isMobileDevice() );
+               $this->assertFalse( $properties->isTabletDevice() );
+       }
+}
diff --git a/tests/phpunit/devices/UADeviceDetectorTest.php 
b/tests/phpunit/devices/UADeviceDetectorTest.php
new file mode 100644
index 0000000..db575f7
--- /dev/null
+++ b/tests/phpunit/devices/UADeviceDetectorTest.php
@@ -0,0 +1,207 @@
+<?php
+
+namespace Tests\MobileFrontend\Devices;
+
+use MediaWikiTestCase;
+use FauxRequest;
+use GlobalVarConfig;
+use MobileFrontend\Devices\UADeviceDetector;
+
+class UADeviceDetectorTest extends MediaWikiTestCase {
+
+       /**
+        * @var UADeviceDetector
+        */
+       private $detector;
+
+       /**
+        * @var FauxRequest
+        */
+       private $request;
+
+       protected function setUp() {
+               parent::setUp();
+
+               $this->detector = new UADeviceDetector();
+               $this->request = new FauxRequest();
+       }
+
+       /**
+        * Creates the list of arguments expected to be returned by a PHPUnit 
data
+        * provider from a list of UAs.
+        *
+        * @param string[] $userAgents
+        * @return array
+        */
+       private static function provideUserAgents( $userAgents ) {
+               return array_map(
+                       function ( $userAgent ) {
+                               return [ $userAgent ];
+                       },
+                       $userAgents
+               );
+       }
+
+       public static function provideMobileUserAgents() {
+               // @codingStandardsIgnoreStart
+               return self::provideUserAgents( [
+                       // Android
+                       'Mozilla/5.0 (Linux; U; Android 2.3.3; zh-tw; 
HTC_Pyramid Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 
Mobile Safari/533.1',
+                       'Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC 
Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 
Mobile Safari/534.30',
+                       // Firefox OS (bug 40919)
+                       'Mozilla/5.0 (Mobile; rv:14.0) Gecko/14.0 Firefox/14.0',
+                       'Mozilla/5.0 (Android; Mobile; rv:20.0) Gecko/20.0 
Firefox/20.0',
+                       // Blackberry 10 (bug 40513)
+                       'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.3+ (KHTML, 
like Gecko) Version/10.0.9.386 Mobile Safari/537.3+',
+                       'Mozilla/5.0 (BlackBerry; U; BlackBerry 9850; en-US) 
AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0.254 Mobile 
Safari/534.11+',
+                       // Windows Phone 8 / IE 10 (bug 41517)
+                       'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; 
Trident/6.0; ARM; Touch; IEMobile/10.0; <Manufacturer>; <Device> 
[;<Operator>])',
+                       // Others
+                       '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',
+                       'Mozilla/5.0 (ipod: U;CPU iPhone OS 2_2 like Mac OS X: 
es_es) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.0 Mobile/3B48b 
Safari/419.3',
+                       'Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) 
AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3B48b Safari/419.3',
+                       'Mozilla/5.0 (SymbianOS/9.1; U; [en]; SymbianOS/91 
Series60/3.0) AppleWebKit/413 (KHTML, like Gecko) Safari/413',
+                       'Mozilla/5.0 (webOS/1.0; U; en-US) AppleWebKit/525.27.1 
(KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/1.0',
+                       'Vodafone/1.0/LG-KU990/V10iBrowser/Obigo-Q05A/3.6 
MMS/LG-MMS-V1.0/1.2 Java/ASVM/1.0 Profile/MIDP-2.0Configuration/CLDC-1.1',
+                       'Vodafone/1.0/0Vodafone543/ V010 05/MIDP-2.0 
Configuration/CLDC-1.1 ObigoInternetBrowser/Q03C',
+                       'DoCoMo/2.0 P07A3(c500;TB;W24H15)',
+                       'KDDI-HI31 UP.Browser/6.2.0.5 (GUI) MMP/2.0',
+                       'Mozilla/4.0 (compatible; MSIE 6.0; KDDI-SA39) Opera 
8.60 [ja]',
+                       // Opera
+                       'Opera/9.50 (J2ME/MIDP; Opera Mini/4.0.10031/298; U; 
en)',
+                       'Opera/9.80 (iPhone; Opera Mini/7.0.4/28.2555; U; fr) 
Presto/2.8.119 Version/11.10',
+                       'Opera/9.51 Beta (Microsoft Windows; PPC; Opera 
Mobi/1718; U; en)',
+                       'Opera/9.80 (Android 4.1.1; Linux; Opera 
Mobi/ADR-1301080958) Presto/2.11.355 Version/12.10',
+                       'Mozilla/4.0 (compatible; Linux 2.6.10) NetFront/3.3 
Kindle/1.0 (screen 600x800)',
+                       'Mozilla/4.0 (compatible; Linux 2.6.22) NetFront/3.4 
Kindle/2.0 (screen 824x1200; rotate)',
+                       // Later Kindles use WebKit
+                       'Mozilla/5.0 (Linux; U; en-US) AppleWebKit/528.5+ 
(KHTML, like Gecko, Safari/528.5+) Version/4.0 Kindle/3.0 (screen 600X800; 
rotate)',
+                       'Mozilla/4.08 (Windows; Mobile Content Viewer/1.0) 
NetFront/3.2',
+                       'SonyEricssonK608i/R2L/SN356841000828910 
Browser/SEMC-Browser/4.2 Profile/MIDP-2.0 Configuration/CLDC-1.1',
+                       'NokiaN73-2/3.0-630.0.2 Series60/3.0 Profile/MIDP-2.0 
Configuration/CLDC-1.1',
+                       'Mozilla/4.0 (PSP (PlayStation Portable); 2.00)',
+                       'Mozilla/5.0 (PLAYSTATION 3; 1.00)',
+                       // Blackberry
+                       'BlackBerry9300/5.0.0.716 Profile/MIDP-2.1 
Configuration/CLDC-1.1 VendorID/133',
+                       'BlackBerry7250/4.0.0 Profile/MIDP-2.0 
Configuration/CLDC-1.1',
+                       // T32827
+                       'SAMSUNG-S8000/S800MXEJA1 SHP/VPP/R5 Jasmine/1.0 
Nextreaming SMM-MMS/1.2.0 profile/MIDP-2.1 configuration/CLDC-1.1 
SS-Widget/S8000-FM',
+                       // WML
+                       'KDDI-KC31 UP.Browser/6.2.0.5 (GUI) MMP/2.0',
+               ] );
+               // @codingStandardsIgnoreEnd
+       }
+
+       public static function provideDesktopUserAgents() {
+               // @codingStandardsIgnoreStart
+               return self::provideUserAgents( [
+                       'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.7) 
Gecko/20060928 (Debian|Debian-1.8.0.7-1) Epiphany/2.14',
+                       'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)',
+                       'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; 
Trident/5.0)',
+                       'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; 
en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 
Safari/534.16',
+                       'Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; 
rv:1.8.1.6) Gecko/20070817 IceWeasel/2.0.0.6-g2',
+                       'Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; 
rv:1.8.1.11) Gecko/20071203 IceCat/2.0.0.11-g1',
+                       'Mozilla/5.0 (compatible; Konqueror/4.3; Linux) 
KHTML/4.3.5 (like Gecko)',
+                       'Links (2.2; GNU/kFreeBSD 6.3-1-486 i686; 80x25)',
+                       'Lynx/2.8.6rel.4 libwww-FM/2.14 SSL-MM/1.4.1 
OpenSSL/0.9.8g',
+                       'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:16.0) 
Gecko/20120815 Firefox/16.0',
+                       'Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.8.131 
Version/11.10',
+                       'Mozilla/5.0 (Macintosh; I; Intel Mac OS X 10_6_7; 
ru-ru) AppleWebKit/534.31+ (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1',
+                       'w3m/0.5.1',
+                       'Googlebot/2.1 (+http://www.google.com/bot.html)',
+                       'Mozilla/5.0 (compatible; googlebot/2.1; 
+http://www.google.com/bot.html)',
+                       'Wget/1.9',
+                       'Mozilla/5.0 (compatible; YandexBot/3.0)',
+               ] );
+               // @codingStandardsIgnoreEnd
+       }
+
+       public static function provideTabletUserAgents() {
+               // @codingStandardsIgnoreStart
+               return self::provideUserAgents( [
+                       // iPad
+                       'Mozilla/5.0 (iPad; CPU OS 7_0_2 like Mac OS X) 
AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A501 
Safari/9537.53',
+                       // Motorola Xoom
+                       'Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom 
Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13',
+                       // Opera Mobile running on a tablet
+                       'Opera/9.80 (Android 4.0.4; Linux; Opera 
Tablet/ADR-1301080958) Presto/2.11.355 Version/12.10',
+                       // Firefox running on a tablet
+                       'Mozilla/5.0 (Android; Tablet; rv:24.0) Gecko/24.0 
Firefox/24.0',
+                       // Nintendo Wii
+                       'Opera/9.00 (Nintendo Wii; U; ; 1309-9; en)',
+                       'Mozilla/5.0 (Nintendo WiiU) AppleWebKit/536.28 (KHTML, 
like Gecko) NX/3.0.3.12.6 NintendoBrowser/2.0.0.9362.EU',
+                       // Samsung Galaxy Tab
+                       'Mozilla/5.0 (Linux; U; Android 4.2.2; nl-nl; GT-P5210 
Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30',
+                       // Kindle Fire, Silk browser operating in "desktop" mode
+                       // (Silk operating in "mobile" mode will only be 
detected as a mobile device.)
+                       'Mozilla/5.0 (Linux; U; en-us; KFTT Build/IML74K) 
AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Safari/535.19 
Silk-Accelerated=true',
+               ] );
+               // @codingStandardsIgnoreEnd
+       }
+
+       private function detectDeviceProperties( $userAgent ) {
+               $this->request->setHeader( 'User-Agent', $userAgent );
+
+               return $this->detector->detectDeviceProperties( $this->request, 
[] );
+       }
+
+       /**
+        * @dataProvider provideMobileUserAgents
+        */
+       public function test_it_classifies_mobile_UAs_as_mobile_devices( 
$userAgent ) {
+               $this->assertTrue(
+                       $this->detectDeviceProperties( $userAgent )
+                               ->isMobileDevice()
+               );
+       }
+
+       /**
+        * @dataProvider provideDesktopUserAgents
+        */
+       public function test_it_doesnt_classify_desktop_UAs_as_mobile_devices( 
$userAgent ) {
+               $this->assertFalse(
+                       $this->detectDeviceProperties( $userAgent )
+                               ->isMobileDevice()
+               );
+       }
+
+       public function 
test_it_doesnt_classify_Samsung_Smart_TVs_as_mobile_devices() {
+               $properties = $this->detectDeviceProperties(
+                       // @codingStandardsIgnoreStart
+                       'Mozilla/5.0 (SMART-TV; Linux; Tizen 2.3) 
AppleWebkit/538.1 (KHTML, like Gecko) SamsungBrowser/1.0 TV Safari/538.1'
+                       // @codingStandardsIgnoreEnd
+               );
+
+               $this->assertFalse( $properties->isMobileDevice() );
+
+               // ---
+
+               $properties = $this->detectDeviceProperties(
+                       // @codingStandardsIgnoreStart
+                       'Mozilla/5.0 (Linux; Android 4.2.2; nl-nl; SAMSUNG 
GT-I9505 Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Version/1.0 
Chrome/18.0.1025.308 Mobile Safari/535.19'
+                       // @codingStandardsIgnoreEnd
+               );
+
+               $this->assertTrue( $properties->isMobileDevice() );
+       }
+
+       /**
+        * @dataProvider provideMobileUserAgents
+        */
+       public function test_it_doesnt_classify_mobile_UAs_as_tablets( 
$userAgent ) {
+               $this->assertFalse(
+                       $this->detectDeviceProperties( $userAgent )
+                               ->isTabletDevice()
+               );
+       }
+
+       /**
+        * @dataProvider provideTabletUserAgents
+        */
+       public function test_it_classifies_tablet_UAs_as_tablets( $userAgent ) {
+               $this->assertTrue(
+                       $this->detectDeviceProperties( $userAgent )
+                               ->isTabletDevice()
+               );
+       }
+}

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I8f5df2b8af407c2ec6763f2c2d7d99d3342065c1
Gerrit-PatchSet: 9
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: Phuedx <samsm...@wikimedia.org>
Gerrit-Reviewer: Bmansurov <bmansu...@wikimedia.org>
Gerrit-Reviewer: Jdlrobson <jrob...@wikimedia.org>
Gerrit-Reviewer: Jhobs <jhob...@wikimedia.org>
Gerrit-Reviewer: Phuedx <samsm...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

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

Reply via email to