2012-03-05 10:26:07 +00:00
< ? php
/*
* This file is part of Composer .
*
* ( c ) Nils Adermann < naderman @ naderman . de >
* Jordi Boggiano < j . boggiano @ seld . be >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Composer\Test\Util ;
use Composer\Util\RemoteFilesystem ;
2013-06-17 13:41:48 +00:00
use Installer\Exception ;
2012-03-05 10:26:07 +00:00
class RemoteFilesystemTest extends \PHPUnit_Framework_TestCase
{
public function testGetOptionsForUrl ()
{
$io = $this -> getMock ( 'Composer\IO\IOInterface' );
$io
-> expects ( $this -> once ())
2012-11-07 12:33:50 +00:00
-> method ( 'hasAuthentication' )
2012-03-05 10:26:07 +00:00
-> will ( $this -> returnValue ( false ))
;
2012-10-18 16:43:31 +00:00
$res = $this -> callGetOptionsForUrl ( $io , array ( 'http://example.org' , array ()));
2012-10-19 10:25:53 +00:00
$this -> assertTrue ( isset ( $res [ 'http' ][ 'header' ]) && is_array ( $res [ 'http' ][ 'header' ]), 'getOptions must return an array with headers' );
$found = false ;
foreach ( $res [ 'http' ][ 'header' ] as $header ) {
if ( 0 === strpos ( $header , 'User-Agent:' )) {
$found = true ;
}
}
$this -> assertTrue ( $found , 'getOptions must have a User-Agent header' );
2012-03-05 10:26:07 +00:00
}
public function testGetOptionsForUrlWithAuthorization ()
{
$io = $this -> getMock ( 'Composer\IO\IOInterface' );
$io
-> expects ( $this -> once ())
2012-11-07 12:33:50 +00:00
-> method ( 'hasAuthentication' )
2012-03-05 10:26:07 +00:00
-> will ( $this -> returnValue ( true ))
;
$io
-> expects ( $this -> once ())
2012-11-07 12:33:50 +00:00
-> method ( 'getAuthentication' )
2012-03-05 10:26:07 +00:00
-> will ( $this -> returnValue ( array ( 'username' => 'login' , 'password' => 'password' )))
;
2012-10-18 16:43:31 +00:00
$options = $this -> callGetOptionsForUrl ( $io , array ( 'http://example.org' , array ()));
2012-10-19 10:25:53 +00:00
$found = false ;
foreach ( $options [ 'http' ][ 'header' ] as $header ) {
if ( 0 === strpos ( $header , 'Authorization: Basic' )) {
$found = true ;
}
}
$this -> assertTrue ( $found , 'getOptions must have an Authorization header' );
2012-03-05 10:26:07 +00:00
}
2012-10-03 13:09:47 +00:00
public function testGetOptionsForUrlWithStreamOptions ()
{
$io = $this -> getMock ( 'Composer\IO\IOInterface' );
$io
-> expects ( $this -> once ())
2012-11-07 12:33:50 +00:00
-> method ( 'hasAuthentication' )
2012-10-03 13:09:47 +00:00
-> will ( $this -> returnValue ( true ))
;
$streamOptions = array ( 'ssl' => array (
'allow_self_signed' => true ,
));
2012-10-18 16:43:31 +00:00
$res = $this -> callGetOptionsForUrl ( $io , array ( 'https://example.org' , array ()), $streamOptions );
2012-10-03 13:09:47 +00:00
$this -> assertTrue ( isset ( $res [ 'ssl' ]) && isset ( $res [ 'ssl' ][ 'allow_self_signed' ]) && true === $res [ 'ssl' ][ 'allow_self_signed' ], 'getOptions must return an array with a allow_self_signed set to true' );
}
2012-10-18 16:43:31 +00:00
public function testGetOptionsForUrlWithCallOptionsKeepsHeader ()
{
$io = $this -> getMock ( 'Composer\IO\IOInterface' );
$io
-> expects ( $this -> once ())
2012-11-07 12:33:50 +00:00
-> method ( 'hasAuthentication' )
2012-10-18 16:43:31 +00:00
-> will ( $this -> returnValue ( true ))
;
$streamOptions = array ( 'http' => array (
'header' => 'Foo: bar' ,
));
$res = $this -> callGetOptionsForUrl ( $io , array ( 'https://example.org' , $streamOptions ));
$this -> assertTrue ( isset ( $res [ 'http' ][ 'header' ]), 'getOptions must return an array with a http.header key' );
2012-10-19 10:25:53 +00:00
$found = false ;
foreach ( $res [ 'http' ][ 'header' ] as $header ) {
if ( $header === 'Foo: bar' ) {
$found = true ;
}
}
$this -> assertTrue ( $found , 'getOptions must have a Foo: bar header' );
$this -> assertGreaterThan ( 1 , count ( $res [ 'http' ][ 'header' ]));
2012-10-18 16:43:31 +00:00
}
2012-03-05 10:26:07 +00:00
public function testCallbackGetFileSize ()
{
$fs = new RemoteFilesystem ( $this -> getMock ( 'Composer\IO\IOInterface' ));
$this -> callCallbackGet ( $fs , STREAM_NOTIFY_FILE_SIZE_IS , 0 , '' , 0 , 0 , 20 );
$this -> assertAttributeEquals ( 20 , 'bytesMax' , $fs );
}
public function testCallbackGetNotifyProgress ()
{
$io = $this -> getMock ( 'Composer\IO\IOInterface' );
$io
-> expects ( $this -> once ())
-> method ( 'overwrite' )
;
$fs = new RemoteFilesystem ( $io );
$this -> setAttribute ( $fs , 'bytesMax' , 20 );
$this -> setAttribute ( $fs , 'progress' , true );
$this -> callCallbackGet ( $fs , STREAM_NOTIFY_PROGRESS , 0 , '' , 0 , 10 , 20 );
$this -> assertAttributeEquals ( 50 , 'lastProgress' , $fs );
}
2014-02-26 15:01:31 +00:00
public function testCallbackGetPassesThrough404 ()
2012-03-05 10:26:07 +00:00
{
$fs = new RemoteFilesystem ( $this -> getMock ( 'Composer\IO\IOInterface' ));
2014-02-26 15:01:31 +00:00
$this -> assertNull ( $this -> callCallbackGet ( $fs , STREAM_NOTIFY_FAILURE , 0 , 'HTTP/1.1 404 Not Found' , 404 , 0 , 0 ));
2012-03-05 10:26:07 +00:00
}
2013-06-17 13:41:48 +00:00
public function testCaptureAuthenticationParamsFromUrl ()
{
$io = $this -> getMock ( 'Composer\IO\IOInterface' );
2013-07-31 12:40:38 +00:00
$io -> expects ( $this -> once ())
-> method ( 'setAuthentication' )
-> with ( $this -> equalTo ( 'example.com' ), $this -> equalTo ( 'user' ), $this -> equalTo ( 'pass' ));
2013-06-17 13:41:48 +00:00
$fs = new RemoteFilesystem ( $io );
2013-07-31 12:40:38 +00:00
try {
$fs -> getContents ( 'example.com' , 'http://user:pass@www.example.com/something' );
} catch ( \Exception $e ) {
$this -> assertInstanceOf ( 'Composer\Downloader\TransportException' , $e );
$this -> assertEquals ( 404 , $e -> getCode ());
}
2013-06-17 13:41:48 +00:00
}
2012-03-05 10:26:07 +00:00
public function testGetContents ()
{
$fs = new RemoteFilesystem ( $this -> getMock ( 'Composer\IO\IOInterface' ));
2012-03-29 13:09:01 +00:00
$this -> assertContains ( 'testGetContents' , $fs -> getContents ( 'http://example.org' , 'file://' . __FILE__ ));
2012-03-05 10:26:07 +00:00
}
public function testCopy ()
{
$fs = new RemoteFilesystem ( $this -> getMock ( 'Composer\IO\IOInterface' ));
$file = tempnam ( sys_get_temp_dir (), 'c' );
2012-03-29 13:09:01 +00:00
$this -> assertTrue ( $fs -> copy ( 'http://example.org' , 'file://' . __FILE__ , $file ));
2012-03-05 10:26:07 +00:00
$this -> assertFileExists ( $file );
2012-03-29 13:09:01 +00:00
$this -> assertContains ( 'testCopy' , file_get_contents ( $file ));
2012-03-05 10:26:07 +00:00
unlink ( $file );
}
2014-02-23 13:33:29 +00:00
/**
* @ group TLS
*/
public function testGetOptionsForUrlCreatesSecureTlsDefaults ()
{
$io = $this -> getMock ( 'Composer\IO\IOInterface' );
2014-02-28 18:46:49 +00:00
$res = $this -> callGetOptionsForUrl ( $io , array ( 'example.org' , array ( 'ssl' => array ( 'cafile' => '/some/path/file.crt' ))), array (), 'http://www.example.org' );
2014-02-23 13:33:29 +00:00
$this -> assertTrue ( isset ( $res [ 'ssl' ][ 'ciphers' ]));
$this -> assertRegExp ( " |!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK| " , $res [ 'ssl' ][ 'ciphers' ]);
$this -> assertTrue ( $res [ 'ssl' ][ 'verify_peer' ]);
$this -> assertTrue ( $res [ 'ssl' ][ 'SNI_enabled' ]);
$this -> assertEquals ( 7 , $res [ 'ssl' ][ 'verify_depth' ]);
2014-02-28 18:46:49 +00:00
$this -> assertEquals ( 'www.example.org' , $res [ 'ssl' ][ 'CN_match' ]);
$this -> assertEquals ( 'www.example.org' , $res [ 'ssl' ][ 'SNI_server_name' ]);
2014-02-23 13:33:29 +00:00
$this -> assertEquals ( '/some/path/file.crt' , $res [ 'ssl' ][ 'cafile' ]);
if ( version_compare ( PHP_VERSION , '5.4.13' ) >= 0 ) {
$this -> assertTrue ( $res [ 'ssl' ][ 'disable_compression' ]);
2014-02-23 14:15:24 +00:00
} else {
$this -> assertFalse ( isset ( $res [ 'ssl' ][ 'disable_compression' ]));
2014-02-23 13:33:29 +00:00
}
}
2014-02-28 18:46:49 +00:00
/**
* @ group TLS
*
* Also illustrates a shortcoming with using originUrl ( which is not a url but an ID )
* TLS would fail under this scenario if Common Name was www . example . org ( i . e . doesn ' t apply to base example . org )
*/
public function testGetOptionsForUrlSelectsOriginIfNoHttpFileUrlAvailable ()
{
$io = $this -> getMock ( 'Composer\IO\IOInterface' );
$res = $this -> callGetOptionsForUrl ( $io , array ( 'example.org' , array ( 'ssl' => array ( 'cafile' => '/some/path/file.crt' ))), array (), 'www.example.org' );
$this -> assertEquals ( 'example.org' , $res [ 'ssl' ][ 'CN_match' ]);
$this -> assertEquals ( 'example.org' , $res [ 'ssl' ][ 'SNI_server_name' ]);
}
protected function callGetOptionsForUrl ( $io , array $args = array (), array $options = array (), $fileUrl = '' )
2012-03-05 10:26:07 +00:00
{
2012-10-03 13:09:47 +00:00
$fs = new RemoteFilesystem ( $io , $options );
2012-03-05 10:26:07 +00:00
$ref = new \ReflectionMethod ( $fs , 'getOptionsForUrl' );
2014-02-28 18:46:49 +00:00
$prop = new \ReflectionProperty ( $fs , 'fileUrl' );
2012-03-05 10:26:07 +00:00
$ref -> setAccessible ( true );
2014-02-28 18:46:49 +00:00
$prop -> setAccessible ( true );
$prop -> setValue ( $fs , $fileUrl );
2012-03-05 10:26:07 +00:00
return $ref -> invokeArgs ( $fs , $args );
}
protected function callCallbackGet ( RemoteFilesystem $fs , $notificationCode , $severity , $message , $messageCode , $bytesTransferred , $bytesMax )
{
$ref = new \ReflectionMethod ( $fs , 'callbackGet' );
$ref -> setAccessible ( true );
$ref -> invoke ( $fs , $notificationCode , $severity , $message , $messageCode , $bytesTransferred , $bytesMax );
}
protected function setAttribute ( $object , $attribute , $value )
{
$attr = new \ReflectionProperty ( $object , $attribute );
$attr -> setAccessible ( true );
$attr -> setValue ( $object , $value );
}
}