2015-08-06 16:43:30 +02:00
< ? php
/**
* @ license MIT License https :// github . com / serbanghita / Mobile - Detect / blob / master / LICENSE . txt
* @ link http :// mobiledetect . net
*/
class BasicTest extends PHPUnit_Framework_TestCase
{
/**
* @ var Mobile_Detect
*/
protected $detect ;
public function testClassExists ()
{
$this -> assertTrue ( class_exists ( 'Mobile_Detect' ));
}
public function setUp ()
{
$this -> detect = new Mobile_Detect ;
}
public function testBasicMethods ()
{
$this -> assertNotEmpty ( $this -> detect -> getScriptVersion () );
$this -> detect -> setHttpHeaders ( array (
'SERVER_SOFTWARE' => 'Apache/2.2.15 (Linux) Whatever/4.0 PHP/5.2.13' ,
'REQUEST_METHOD' => 'POST' ,
'HTTP_HOST' => 'home.ghita.org' ,
'HTTP_X_REAL_IP' => '1.2.3.4' ,
'HTTP_X_FORWARDED_FOR' => '1.2.3.5' ,
'HTTP_CONNECTION' => 'close' ,
'HTTP_USER_AGENT' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_0_1 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A523 Safari/8536.25' ,
'HTTP_ACCEPT' => 'text/vnd.wap.wml, application/json, text/javascript, */*; q=0.01' ,
'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5' ,
'HTTP_ACCEPT_ENCODING' => 'gzip, deflate' ,
'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest' ,
'HTTP_REFERER' => 'http://mobiledetect.net' ,
'HTTP_PRAGMA' => 'no-cache' ,
'HTTP_CACHE_CONTROL' => 'no-cache' ,
'REMOTE_ADDR' => '11.22.33.44' ,
'REQUEST_TIME' => '01-10-2012 07:57'
));
//12 because only 12 start with HTTP_
$this -> assertCount ( 12 , $this -> detect -> getHttpHeaders () );
$this -> assertTrue ( $this -> detect -> checkHttpHeadersForMobile () );
$this -> detect -> setUserAgent ( 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_0_1 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A523 Safari/8536.25' );
$this -> assertNotEmpty ( $this -> detect -> getUserAgent () );
$this -> assertTrue ( $this -> detect -> isMobile () );
$this -> assertFalse ( $this -> detect -> isTablet () );
$this -> assertTrue ( $this -> detect -> isIphone () );
$this -> assertTrue ( $this -> detect -> isiphone () );
$this -> assertTrue ( $this -> detect -> isiOS () );
$this -> assertTrue ( $this -> detect -> isios () );
$this -> assertTrue ( $this -> detect -> is ( 'iphone' ) );
$this -> assertTrue ( $this -> detect -> is ( 'ios' ) );
}
public function headersProvider ()
{
return array (
array ( array (
'SERVER_SOFTWARE' => 'Apache/2.2.15 (Linux) Whatever/4.0 PHP/5.2.13' ,
'REQUEST_METHOD' => 'POST' ,
'HTTP_HOST' => 'home.ghita.org' ,
'HTTP_X_REAL_IP' => '1.2.3.4' ,
'HTTP_X_FORWARDED_FOR' => '1.2.3.5' ,
'HTTP_CONNECTION' => 'close' ,
'HTTP_USER_AGENT' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_0_1 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A523 Safari/8536.25' ,
'HTTP_ACCEPT' => 'text/vnd.wap.wml, application/json, text/javascript, */*; q=0.01' ,
'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5' ,
'HTTP_ACCEPT_ENCODING' => 'gzip, deflate' ,
'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest' ,
'HTTP_REFERER' => 'http://mobiledetect.net' ,
'HTTP_PRAGMA' => 'no-cache' ,
'HTTP_CACHE_CONTROL' => 'no-cache' ,
'REMOTE_ADDR' => '11.22.33.44' ,
'REQUEST_TIME' => '01-10-2012 07:57'
)),
array ( array (
'SERVER_SOFTWARE' => 'Rogue software' ,
'REQUEST_METHOD' => 'GET' ,
'REMOTE_ADDR' => '8.8.8.8' ,
'REQUEST_TIME' => '07-10-2013 23:56' ,
'HTTP_USER_AGENT' => " garbage/1.0 "
)),
array ( array (
'SERVER_SOFTWARE' => 'Apache/1.3.17 (Linux) PHP/5.5.2' ,
'REQUEST_METHOD' => 'HEAD' ,
'HTTP_USER_AGENT' => 'Mozilla/5.0 (Linux; U; Android 1.5; en-us; ADR6200 Build/CUPCAKE) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1' ,
'REMOTE_ADDR' => '1.250.250.0' ,
'REQUEST_TIME' => '06-12-2006 11:06'
)),
);
}
/**
* @ dataProvider headersProvider
* @ covers Mobile_Detect :: getHttpHeader
*/
public function testConstructorInjection ( array $headers )
{
$md = new Mobile_Detect ( $headers );
foreach ( $headers as $header => $value ) {
if ( substr ( $header , 0 , 5 ) !== 'HTTP_' ) {
//make sure it wasn't set
$this -> assertNull ( $md -> getHttpHeader ( $value ));
} else {
//make sure it's equal
$this -> assertEquals ( $value , $md -> getHttpHeader ( $header ));
}
}
//verify some of the headers work with the translated getter
$this -> assertNull ( $md -> getHttpHeader ( 'Remote-Addr' ));
$this -> assertNull ( $md -> getHttpHeader ( 'Server-Software' ));
$this -> assertEquals ( $headers [ 'HTTP_USER_AGENT' ], $md -> getHttpHeader ( 'User-Agent' ));
}
/**
* @ dataProvider headersProvider
* @ covers Mobile_Detect :: getHttpHeader
*/
public function testInvalidHeader ( $headers )
{
$md = new Mobile_Detect ( $headers );
$this -> assertNull ( $md -> getHttpHeader ( 'garbage_is_Garbage' ));
}
public function userAgentProvider ()
{
return array (
array ( array (
'HTTP_USER_AGENT' => 'blah'
), 'blah' ),
array ( array (
'HTTP_USER_AGENT' => 'iphone' ,
'HTTP_X_OPERAMINI_PHONE_UA' => 'some other stuff'
), 'iphone some other stuff' ),
array ( array (
'HTTP_X_DEVICE_USER_AGENT' => 'hello world'
), 'hello world' ),
array ( array (), null )
);
}
/**
* @ dataProvider userAgentProvider
2015-12-07 13:53:59 +01:00
* @ covers Mobile_Detect :: setUserAgent
* @ covers Mobile_Detect :: getUserAgent
2015-08-06 16:43:30 +02:00
*/
public function testGetUserAgent ( $headers , $expectedUserAgent )
{
$md = new Mobile_Detect ( $headers );
$md -> setUserAgent ();
$this -> assertSame ( $expectedUserAgent , $md -> getUserAgent ());
}
/**
* Headers should be reset when you use setHttpHeaders .
* @ covers Mobile_Detect :: setHttpHeaders
* @ issue #144
*/
public function testSetHttpHeaders ()
{
$header1 = array ( 'HTTP_PINK_PONY' => 'I secretly love ponies >_>' );
$md = new Mobile_Detect ( $header1 );
$this -> assertSame ( $md -> getHttpHeaders (), $header1 );
$header2 = array ( 'HTTP_FIRE_BREATHING_DRAGON' => 'yeah!' );
$md -> setHttpHeaders ( $header2 );
$this -> assertSame ( $md -> getHttpHeaders (), $header2 );
}
/**
2015-12-07 13:53:59 +01:00
* Read response from cloudfront , if the cloudfront headers are detected
* @ covers Mobile_Detect :: setCfHeaders
*/
public function testSetCfHeaders ()
{
// Test mobile detected
$header1 = array (
'HTTP_CLOUDFRONT_IS_DESKTOP_VIEWER' => 'false' ,
'HTTP_CLOUDFRONT_IS_MOBILE_VIEWER' => 'true' ,
'HTTP_CLOUDFRONT_IS_TABLET_VIEWER' => 'false'
);
$md = new Mobile_Detect ( $header1 );
$this -> assertSame ( $md -> getCfHeaders (), $header1 );
$this -> assertSame ( $md -> getUserAgent (), 'Amazon CloudFront' );
$this -> assertSame ( $md -> isTablet (), false );
$this -> assertSame ( $md -> isMobile (), true );
// Test neither mobile nor tablet (desktop)
$header2 = array (
'HTTP_CLOUDFRONT_IS_DESKTOP_VIEWER' => 'true' ,
'HTTP_CLOUDFRONT_IS_MOBILE_VIEWER' => 'false' ,
'HTTP_CLOUDFRONT_IS_TABLET_VIEWER' => 'false'
);
$md -> setHttpHeaders ( $header2 );
$this -> assertSame ( $md -> getCfHeaders (), $header2 );
$this -> assertSame ( $md -> getUserAgent (), 'Amazon CloudFront' );
$this -> assertSame ( $md -> isTablet (), false );
$this -> assertSame ( $md -> isMobile (), false );
// Test tablet detected
$header3 = array (
'HTTP_CLOUDFRONT_IS_DESKTOP_VIEWER' => 'false' ,
'HTTP_CLOUDFRONT_IS_MOBILE_VIEWER' => 'false' ,
'HTTP_CLOUDFRONT_IS_TABLET_VIEWER' => 'true'
);
$md -> setCfHeaders ( $header3 );
$this -> assertSame ( $md -> getCfHeaders (), $header3 );
$this -> assertSame ( $md -> getUserAgent (), 'Amazon CloudFront' );
$this -> assertSame ( $md -> isTablet (), true );
$this -> assertSame ( $md -> isMobile (), false );
// Check if the headers are cleared
$header4 = array ();
$md -> setHttpHeaders ( $header4 );
$this -> assertSame ( $md -> getCfHeaders (), $header4 );
}
/**
* @ covers Mobile_Detect :: setUserAgent
* @ covers Mobile_Detect :: getUserAgent
2015-08-06 16:43:30 +02:00
*/
public function testSetUserAgent ()
{
$md = new Mobile_Detect ( array ());
$md -> setUserAgent ( 'hello world' );
$this -> assertSame ( 'hello world' , $md -> getUserAgent ());
}
/**
* @ covers Mobile_Detect :: setDetectionType
*/
public function testSetDetectionType ()
{
$md = new Mobile_Detect ( array ());
$md -> setDetectionType ( 'bskdfjhs' );
$this -> assertAttributeEquals (
Mobile_Detect :: DETECTION_TYPE_MOBILE ,
'detectionType' ,
$md
);
$md -> setDetectionType ();
$this -> assertAttributeEquals (
Mobile_Detect :: DETECTION_TYPE_MOBILE ,
'detectionType' ,
$md
);
$md -> setDetectionType ( Mobile_Detect :: DETECTION_TYPE_MOBILE );
$this -> assertAttributeEquals (
Mobile_Detect :: DETECTION_TYPE_MOBILE ,
'detectionType' ,
$md
);
$md -> setDetectionType ( Mobile_Detect :: DETECTION_TYPE_EXTENDED );
$this -> assertAttributeEquals (
Mobile_Detect :: DETECTION_TYPE_EXTENDED ,
'detectionType' ,
$md
);
}
//special headers that give 'quick' indication that a device is mobile
public function quickHeadersData ()
{
return array (
array ( array (
'HTTP_ACCEPT' => 'application/json; q=0.2, application/x-obml2d; q=0.8, image/gif; q=0.99, */*'
)),
array ( array (
'HTTP_ACCEPT' => 'text/*; q=0.1, application/vnd.rim.html'
)),
array ( array (
'HTTP_ACCEPT' => 'text/vnd.wap.wml' ,
)),
array ( array (
'HTTP_ACCEPT' => 'application/vnd.wap.xhtml+xml' ,
)),
array ( array (
'HTTP_X_WAP_PROFILE' => 'hello' ,
)),
array ( array (
'HTTP_X_WAP_CLIENTID' => ''
)),
array ( array (
'HTTP_WAP_CONNECTION' => ''
)),
array ( array (
'HTTP_PROFILE' => ''
)),
array ( array (
'HTTP_X_OPERAMINI_PHONE_UA' => ''
)),
array ( array (
'HTTP_X_NOKIA_GATEWAY_ID' => ''
)),
array ( array (
'HTTP_X_ORANGE_ID' => ''
)),
array ( array (
'HTTP_X_VODAFONE_3GPDPCONTEXT' => ''
)),
array ( array (
'HTTP_X_HUAWEI_USERID' => ''
)),
array ( array (
'HTTP_UA_OS' => ''
)),
array ( array (
'HTTP_X_MOBILE_GATEWAY' => ''
)),
array ( array (
'HTTP_X_ATT_DEVICEID' => ''
)),
array ( array (
'HTTP_UA_CPU' => 'ARM'
))
);
}
/**
* @ dataProvider quickHeadersData
* @ covers Mobile_Detect :: checkHttpHeadersForMobile
*/
public function testQuickHeaders ( $headers )
{
$md = new Mobile_Detect ( $headers );
$this -> assertTrue ( $md -> checkHttpHeadersForMobile ());
}
// Headers that are not mobile.
public function quickNonMobileHeadersData ()
{
return array (
array ( array (
'HTTP_UA_CPU' => 'AMD64'
)),
array ( array (
'HTTP_UA_CPU' => 'X86'
)),
array ( array (
'HTTP_ACCEPT' => 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01'
)),
array ( array (
'HTTP_REQUEST_METHOD' => 'DELETE'
)),
array ( array (
'HTTP_VIA' => '1.1 ws-proxy.stuff.co.il C0A800FA'
)),
);
}
/**
* @ dataProvider quickNonMobileHeadersData
* @ covers Mobile_Detect :: checkHttpHeadersForMobile
*/
public function testNonMobileQuickHeaders ( $headers )
{
$md = new Mobile_Detect ( $headers );
$this -> assertFalse ( $md -> checkHttpHeadersForMobile ());
}
/**
* @ expectedException BadMethodCallException
* @ coversNothing
*/
public function testBadMethodCall ()
{
$md = new Mobile_Detect ( array ());
$md -> badmethodthatdoesntexistatall ();
}
public function versionDataProvider ()
{
return array (
array (
'Mozilla/5.0 (Linux; Android 4.0.4; ARCHOS 80G9 Build/IMM76D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19' ,
'Android' ,
'4.0.4' ,
4.04
),
array (
'Mozilla/5.0 (Linux; Android 4.0.4; ARCHOS 80G9 Build/IMM76D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19' ,
'Webkit' ,
'535.19' ,
535.19
),
array (
'Mozilla/5.0 (Linux; Android 4.0.4; ARCHOS 80G9 Build/IMM76D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19' ,
'Chrome' ,
'18.0.1025.166' ,
18.01025166
),
array (
'Mozilla/5.0 (BlackBerry; U; BlackBerry 9700; en-US) AppleWebKit/534.8 (KHTML, like Gecko) Version/6.0.0.448 Mobile Safari/534.8' ,
'BlackBerry' ,
'6.0.0.448' ,
6.00448
),
array (
'Mozilla/5.0 (BlackBerry; U; BlackBerry 9700; en-US) AppleWebKit/534.8 (KHTML, like Gecko) Version/6.0.0.448 Mobile Safari/534.8' ,
'Webkit' ,
'534.8' ,
534.8
),
array (
'Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en-GB) AppleWebKit/534.8+ (KHTML, like Gecko) Version/6.0.0.546 Mobile Safari/534.8+' ,
'BlackBerry' ,
'6.0.0.546' ,
6.00546
)
);
}
/**
* @ dataProvider versionDataProvider
* @ covers Mobile_Detect :: version
*/
public function testVersionExtraction ( $userAgent , $property , $stringVersion , $floatVersion )
{
$md = new Mobile_Detect ( array ( 'HTTP_USER_AGENT' => $userAgent ));
$prop = $md -> version ( $property );
$this -> assertSame ( $stringVersion , $prop );
$prop = $md -> version ( $property , 'float' );
$this -> assertSame ( $floatVersion , $prop );
//assert that garbage data is always === false
$prop = $md -> version ( 'garbage input is always garbage' );
$this -> assertFalse ( $prop );
}
/**
* @ covers Mobile_Detect :: getMobileDetectionRules
*/
public function testRules ()
{
$md = new Mobile_Detect ;
$count = array_sum ( array (
count ( Mobile_Detect :: getPhoneDevices ()),
count ( Mobile_Detect :: getTabletDevices ()),
count ( Mobile_Detect :: getOperatingSystems ()),
count ( Mobile_Detect :: getBrowsers ())
));
$rules = $md -> getRules ();
$this -> assertEquals ( $count , count ( $rules ));
}
/**
* @ covers Mobile_Detect :: getMobileDetectionRulesExtended
*/
public function testRulesExtended ()
{
$md = new Mobile_Detect ;
$count = array_sum ( array (
count ( Mobile_Detect :: getPhoneDevices ()),
count ( Mobile_Detect :: getTabletDevices ()),
count ( Mobile_Detect :: getOperatingSystems ()),
count ( Mobile_Detect :: getBrowsers ()),
count ( Mobile_Detect :: getUtilities ())
));
$md -> setDetectionType ( Mobile_Detect :: DETECTION_TYPE_EXTENDED );
$rules = $md -> getRules ();
$this -> assertEquals ( $count , count ( $rules ));
}
/**
* @ covers Mobile_Detect :: getScriptVersion
*/
public function testScriptVersion ()
{
$v = Mobile_Detect :: getScriptVersion ();
2015-12-07 13:53:59 +01:00
$formatCheck = ( bool ) preg_match ( '/^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9])?$/' , $v );
2015-08-06 16:43:30 +02:00
$this -> assertTrue ( $formatCheck , " Fails the semantic version test. The version " . var_export ( $v , true )
. ' does not match X.Y.Z pattern' );
}
public function crazyVersionNumbers ()
{
return array (
array ( '2.5.6' , 2.56 ),
array ( '12142.2142.412521.24.152' , 12142.214241252124152 ),
array ( '6_3' , 6.3 ),
array ( '4_7 /7 7 12_9' , 4.777129 ),
array ( '49' , 49.0 ),
array ( '2.6.x' , 2.6 ),
array ( '45.6.1.x.12' , 45.61 )
);
}
/**
* @ dataProvider crazyVersionNumbers
* @ covers Mobile_Detect :: prepareVersionNo
*/
public function testPrepareVersionNo ( $raw , $expected )
{
$md = new Mobile_Detect ;
$actual = $md -> prepareVersionNo ( $raw );
$this -> assertSame ( $expected , $actual , " We expected " . var_export ( $raw , true ) . " to convert to "
. var_export ( $expected , true ) . ', but got ' . var_export ( $actual , true ) . ' instead' );
}
}