Split HttpTest and SessionTest to unit and integration
This way it moves 73 more tests to unit tests Bug: T87781 Change-Id: I963488450bb355573d71ae31b57d71683ce51683
This commit is contained in:
parent
3ec2e54afa
commit
2c046e1b6c
4 changed files with 374 additions and 349 deletions
|
|
@ -7,20 +7,6 @@
|
|||
*/
|
||||
class HttpTest extends MediaWikiTestCase {
|
||||
|
||||
/**
|
||||
* Test Http::isValidURI()
|
||||
* T29854 : Http::isValidURI is too lax
|
||||
* @dataProvider provideURI
|
||||
* @covers Http::isValidURI
|
||||
*/
|
||||
public function testIsValidUri( $expect, $URI, $message = '' ) {
|
||||
$this->assertEquals(
|
||||
$expect,
|
||||
(bool)Http::isValidURI( $URI ),
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Http::getProxy
|
||||
*/
|
||||
|
|
@ -41,71 +27,4 @@ class HttpTest extends MediaWikiTestCase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Feeds URI to test a long regular expression in Http::isValidURI
|
||||
*/
|
||||
public static function provideURI() {
|
||||
/** Format: 'boolean expectation', 'URI to test', 'Optional message' */
|
||||
return [
|
||||
[ false, '¿non sens before!! http://a', 'Allow anything before URI' ],
|
||||
|
||||
# (http|https) - only two schemes allowed
|
||||
[ true, 'http://www.example.org/' ],
|
||||
[ true, 'https://www.example.org/' ],
|
||||
[ true, 'http://www.example.org', 'URI without directory' ],
|
||||
[ true, 'http://a', 'Short name' ],
|
||||
[ true, 'http://étoile', 'Allow UTF-8 in hostname' ], # 'étoile' is french for 'star'
|
||||
[ false, '\\host\directory', 'CIFS share' ],
|
||||
[ false, 'gopher://host/dir', 'Reject gopher scheme' ],
|
||||
[ false, 'telnet://host', 'Reject telnet scheme' ],
|
||||
|
||||
# :\/\/ - double slashes
|
||||
[ false, 'http//example.org', 'Reject missing colon in protocol' ],
|
||||
[ false, 'http:/example.org', 'Reject missing slash in protocol' ],
|
||||
[ false, 'http:example.org', 'Must have two slashes' ],
|
||||
# Following fail since hostname can be made of anything
|
||||
[ false, 'http:///example.org', 'Must have exactly two slashes, not three' ],
|
||||
|
||||
# (\w+:{0,1}\w*@)? - optional user:pass
|
||||
[ true, 'http://user@host', 'Username provided' ],
|
||||
[ true, 'http://user:@host', 'Username provided, no password' ],
|
||||
[ true, 'http://user:pass@host', 'Username and password provided' ],
|
||||
|
||||
# (\S+) - host part is made of anything not whitespaces
|
||||
// commented these out in order to remove @group Broken
|
||||
// @todo are these valid tests? if so, fix Http::isValidURI so it can handle them
|
||||
// [ false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ],
|
||||
// [ false, 'http://exam:ple.org/', 'hostname can not use colons!' ],
|
||||
|
||||
# (:[0-9]+)? - port number
|
||||
[ true, 'http://example.org:80/' ],
|
||||
[ true, 'https://example.org:80/' ],
|
||||
[ true, 'http://example.org:443/' ],
|
||||
[ true, 'https://example.org:443/' ],
|
||||
|
||||
# Part after the hostname is / or / with something else
|
||||
[ true, 'http://example/#' ],
|
||||
[ true, 'http://example/!' ],
|
||||
[ true, 'http://example/:' ],
|
||||
[ true, 'http://example/.' ],
|
||||
[ true, 'http://example/?' ],
|
||||
[ true, 'http://example/+' ],
|
||||
[ true, 'http://example/=' ],
|
||||
[ true, 'http://example/&' ],
|
||||
[ true, 'http://example/%' ],
|
||||
[ true, 'http://example/@' ],
|
||||
[ true, 'http://example/-' ],
|
||||
[ true, 'http://example//' ],
|
||||
[ true, 'http://example/&' ],
|
||||
|
||||
# Fragment
|
||||
[ true, 'http://exam#ple.org', ], # This one is valid, really!
|
||||
[ true, 'http://example.org:80#anchor' ],
|
||||
[ true, 'http://example.org/?id#anchor' ],
|
||||
[ true, 'http://example.org/?#anchor' ],
|
||||
|
||||
[ false, 'http://a ¿non !!sens after', 'Allow anything after URI' ],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,214 +13,6 @@ use Wikimedia\TestingAccessWrapper;
|
|||
*/
|
||||
class SessionTest extends MediaWikiTestCase {
|
||||
|
||||
public function testConstructor() {
|
||||
$backend = TestUtils::getDummySessionBackend();
|
||||
TestingAccessWrapper::newFromObject( $backend )->requests = [ -1 => 'dummy' ];
|
||||
TestingAccessWrapper::newFromObject( $backend )->id = new SessionId( 'abc' );
|
||||
|
||||
$session = new Session( $backend, 42, new \TestLogger );
|
||||
$priv = TestingAccessWrapper::newFromObject( $session );
|
||||
$this->assertSame( $backend, $priv->backend );
|
||||
$this->assertSame( 42, $priv->index );
|
||||
|
||||
$request = new \FauxRequest();
|
||||
$priv2 = TestingAccessWrapper::newFromObject( $session->sessionWithRequest( $request ) );
|
||||
$this->assertSame( $backend, $priv2->backend );
|
||||
$this->assertNotSame( $priv->index, $priv2->index );
|
||||
$this->assertSame( $request, $priv2->getRequest() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMethods
|
||||
* @param string $m Method to test
|
||||
* @param array $args Arguments to pass to the method
|
||||
* @param bool $index Whether the backend method gets passed the index
|
||||
* @param bool $ret Whether the method returns a value
|
||||
*/
|
||||
public function testMethods( $m, $args, $index, $ret ) {
|
||||
$mock = $this->getMockBuilder( DummySessionBackend::class )
|
||||
->setMethods( [ $m, 'deregisterSession' ] )
|
||||
->getMock();
|
||||
$mock->expects( $this->once() )->method( 'deregisterSession' )
|
||||
->with( $this->identicalTo( 42 ) );
|
||||
|
||||
$tmp = $mock->expects( $this->once() )->method( $m );
|
||||
$expectArgs = [];
|
||||
if ( $index ) {
|
||||
$expectArgs[] = $this->identicalTo( 42 );
|
||||
}
|
||||
foreach ( $args as $arg ) {
|
||||
$expectArgs[] = $this->identicalTo( $arg );
|
||||
}
|
||||
$tmp = call_user_func_array( [ $tmp, 'with' ], $expectArgs );
|
||||
|
||||
$retval = new \stdClass;
|
||||
$tmp->will( $this->returnValue( $retval ) );
|
||||
|
||||
$session = TestUtils::getDummySession( $mock, 42 );
|
||||
|
||||
if ( $ret ) {
|
||||
$this->assertSame( $retval, call_user_func_array( [ $session, $m ], $args ) );
|
||||
} else {
|
||||
$this->assertNull( call_user_func_array( [ $session, $m ], $args ) );
|
||||
}
|
||||
|
||||
// Trigger Session destructor
|
||||
$session = null;
|
||||
}
|
||||
|
||||
public static function provideMethods() {
|
||||
return [
|
||||
[ 'getId', [], false, true ],
|
||||
[ 'getSessionId', [], false, true ],
|
||||
[ 'resetId', [], false, true ],
|
||||
[ 'getProvider', [], false, true ],
|
||||
[ 'isPersistent', [], false, true ],
|
||||
[ 'persist', [], false, false ],
|
||||
[ 'unpersist', [], false, false ],
|
||||
[ 'shouldRememberUser', [], false, true ],
|
||||
[ 'setRememberUser', [ true ], false, false ],
|
||||
[ 'getRequest', [], true, true ],
|
||||
[ 'getUser', [], false, true ],
|
||||
[ 'getAllowedUserRights', [], false, true ],
|
||||
[ 'canSetUser', [], false, true ],
|
||||
[ 'setUser', [ new \stdClass ], false, false ],
|
||||
[ 'suggestLoginUsername', [], true, true ],
|
||||
[ 'shouldForceHTTPS', [], false, true ],
|
||||
[ 'setForceHTTPS', [ true ], false, false ],
|
||||
[ 'getLoggedOutTimestamp', [], false, true ],
|
||||
[ 'setLoggedOutTimestamp', [ 123 ], false, false ],
|
||||
[ 'getProviderMetadata', [], false, true ],
|
||||
[ 'save', [], false, false ],
|
||||
[ 'delaySave', [], false, true ],
|
||||
[ 'renew', [], false, false ],
|
||||
];
|
||||
}
|
||||
|
||||
public function testDataAccess() {
|
||||
$session = TestUtils::getDummySession();
|
||||
$backend = TestingAccessWrapper::newFromObject( $session )->backend;
|
||||
|
||||
$this->assertEquals( 1, $session->get( 'foo' ) );
|
||||
$this->assertEquals( 'zero', $session->get( 0 ) );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$this->assertEquals( null, $session->get( 'null' ) );
|
||||
$this->assertEquals( 'default', $session->get( 'null', 'default' ) );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$session->set( 'foo', 55 );
|
||||
$this->assertEquals( 55, $backend->data['foo'] );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
|
||||
$session->set( 1, 'one' );
|
||||
$this->assertEquals( 'one', $backend->data[1] );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
|
||||
$session->set( 1, 'one' );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$this->assertTrue( $session->exists( 'foo' ) );
|
||||
$this->assertTrue( $session->exists( 1 ) );
|
||||
$this->assertFalse( $session->exists( 'null' ) );
|
||||
$this->assertFalse( $session->exists( 100 ) );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$session->remove( 'foo' );
|
||||
$this->assertArrayNotHasKey( 'foo', $backend->data );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
$session->remove( 1 );
|
||||
$this->assertArrayNotHasKey( 1, $backend->data );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
|
||||
$session->remove( 101 );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$backend->data = [ 'a', 'b', '?' => 'c' ];
|
||||
$this->assertSame( 3, $session->count() );
|
||||
$this->assertSame( 3, count( $session ) );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$data = [];
|
||||
foreach ( $session as $key => $value ) {
|
||||
$data[$key] = $value;
|
||||
}
|
||||
$this->assertEquals( $backend->data, $data );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$this->assertEquals( $backend->data, iterator_to_array( $session ) );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
}
|
||||
|
||||
public function testArrayAccess() {
|
||||
$logger = new \TestLogger;
|
||||
$session = TestUtils::getDummySession( null, -1, $logger );
|
||||
$backend = TestingAccessWrapper::newFromObject( $session )->backend;
|
||||
|
||||
$this->assertEquals( 1, $session['foo'] );
|
||||
$this->assertEquals( 'zero', $session[0] );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$logger->setCollect( true );
|
||||
$this->assertEquals( null, $session['null'] );
|
||||
$logger->setCollect( false );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
$this->assertSame( [
|
||||
[ LogLevel::DEBUG, 'Undefined index (auto-adds to session with a null value): null' ]
|
||||
], $logger->getBuffer() );
|
||||
$logger->clearBuffer();
|
||||
|
||||
$session['foo'] = 55;
|
||||
$this->assertEquals( 55, $backend->data['foo'] );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
|
||||
$session[1] = 'one';
|
||||
$this->assertEquals( 'one', $backend->data[1] );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
|
||||
$session[1] = 'one';
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$session['bar'] = [ 'baz' => [] ];
|
||||
$session['bar']['baz']['quux'] = 2;
|
||||
$this->assertEquals( [ 'baz' => [ 'quux' => 2 ] ], $backend->data['bar'] );
|
||||
|
||||
$logger->setCollect( true );
|
||||
$session['bar2']['baz']['quux'] = 3;
|
||||
$logger->setCollect( false );
|
||||
$this->assertEquals( [ 'baz' => [ 'quux' => 3 ] ], $backend->data['bar2'] );
|
||||
$this->assertSame( [
|
||||
[ LogLevel::DEBUG, 'Undefined index (auto-adds to session with a null value): bar2' ]
|
||||
], $logger->getBuffer() );
|
||||
$logger->clearBuffer();
|
||||
|
||||
$backend->dirty = false;
|
||||
$this->assertTrue( isset( $session['foo'] ) );
|
||||
$this->assertTrue( isset( $session[1] ) );
|
||||
$this->assertFalse( isset( $session['null'] ) );
|
||||
$this->assertFalse( isset( $session['missing'] ) );
|
||||
$this->assertFalse( isset( $session[100] ) );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
unset( $session['foo'] );
|
||||
$this->assertArrayNotHasKey( 'foo', $backend->data );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
unset( $session[1] );
|
||||
$this->assertArrayNotHasKey( 1, $backend->data );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
|
||||
unset( $session[101] );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
}
|
||||
|
||||
public function testClear() {
|
||||
$session = TestUtils::getDummySession();
|
||||
$priv = TestingAccessWrapper::newFromObject( $session );
|
||||
|
|
@ -268,66 +60,6 @@ class SessionTest extends MediaWikiTestCase {
|
|||
$this->assertTrue( $backend->dirty );
|
||||
}
|
||||
|
||||
public function testTokens() {
|
||||
$session = TestUtils::getDummySession();
|
||||
$priv = TestingAccessWrapper::newFromObject( $session );
|
||||
$backend = $priv->backend;
|
||||
|
||||
$token = TestingAccessWrapper::newFromObject( $session->getToken() );
|
||||
$this->assertArrayHasKey( 'wsTokenSecrets', $backend->data );
|
||||
$this->assertArrayHasKey( 'default', $backend->data['wsTokenSecrets'] );
|
||||
$secret = $backend->data['wsTokenSecrets']['default'];
|
||||
$this->assertSame( $secret, $token->secret );
|
||||
$this->assertSame( '', $token->salt );
|
||||
$this->assertTrue( $token->wasNew() );
|
||||
|
||||
$token = TestingAccessWrapper::newFromObject( $session->getToken( 'foo' ) );
|
||||
$this->assertSame( $secret, $token->secret );
|
||||
$this->assertSame( 'foo', $token->salt );
|
||||
$this->assertFalse( $token->wasNew() );
|
||||
|
||||
$backend->data['wsTokenSecrets']['secret'] = 'sekret';
|
||||
$token = TestingAccessWrapper::newFromObject(
|
||||
$session->getToken( [ 'bar', 'baz' ], 'secret' )
|
||||
);
|
||||
$this->assertSame( 'sekret', $token->secret );
|
||||
$this->assertSame( 'bar|baz', $token->salt );
|
||||
$this->assertFalse( $token->wasNew() );
|
||||
|
||||
$session->resetToken( 'secret' );
|
||||
$this->assertArrayHasKey( 'wsTokenSecrets', $backend->data );
|
||||
$this->assertArrayHasKey( 'default', $backend->data['wsTokenSecrets'] );
|
||||
$this->assertArrayNotHasKey( 'secret', $backend->data['wsTokenSecrets'] );
|
||||
|
||||
$session->resetAllTokens();
|
||||
$this->assertArrayNotHasKey( 'wsTokenSecrets', $backend->data );
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideSecretsRoundTripping
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function testSecretsRoundTripping( $data ) {
|
||||
$session = TestUtils::getDummySession();
|
||||
|
||||
// Simple round-trip
|
||||
$session->setSecret( 'secret', $data );
|
||||
$this->assertNotEquals( $data, $session->get( 'secret' ) );
|
||||
$this->assertEquals( $data, $session->getSecret( 'secret', 'defaulted' ) );
|
||||
}
|
||||
|
||||
public static function provideSecretsRoundTripping() {
|
||||
return [
|
||||
[ 'Foobar' ],
|
||||
[ 42 ],
|
||||
[ [ 'foo', 'bar' => 'baz', 'subarray' => [ 1, 2, 3 ] ] ],
|
||||
[ (object)[ 'foo', 'bar' => 'baz', 'subarray' => [ 1, 2, 3 ] ] ],
|
||||
[ true ],
|
||||
[ false ],
|
||||
[ null ],
|
||||
];
|
||||
}
|
||||
|
||||
public function testSecrets() {
|
||||
$logger = new \TestLogger;
|
||||
$session = TestUtils::getDummySession( null, -1, $logger );
|
||||
|
|
@ -370,4 +102,29 @@ class SessionTest extends MediaWikiTestCase {
|
|||
\Wikimedia\restoreWarnings();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideSecretsRoundTripping
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function testSecretsRoundTripping( $data ) {
|
||||
$session = TestUtils::getDummySession();
|
||||
|
||||
// Simple round-trip
|
||||
$session->setSecret( 'secret', $data );
|
||||
$this->assertNotEquals( $data, $session->get( 'secret' ) );
|
||||
$this->assertEquals( $data, $session->getSecret( 'secret', 'defaulted' ) );
|
||||
}
|
||||
|
||||
public static function provideSecretsRoundTripping() {
|
||||
return [
|
||||
[ 'Foobar' ],
|
||||
[ 42 ],
|
||||
[ [ 'foo', 'bar' => 'baz', 'subarray' => [ 1, 2, 3 ] ] ],
|
||||
[ (object)[ 'foo', 'bar' => 'baz', 'subarray' => [ 1, 2, 3 ] ] ],
|
||||
[ true ],
|
||||
[ false ],
|
||||
[ null ],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
91
tests/phpunit/unit/includes/http/HttpUnitTest.php
Normal file
91
tests/phpunit/unit/includes/http/HttpUnitTest.php
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @covers Http
|
||||
* @group Http
|
||||
* @group small
|
||||
*/
|
||||
class HttpUnitTest extends MediaWikiUnitTestCase {
|
||||
|
||||
/**
|
||||
* Test Http::isValidURI()
|
||||
* T29854 : Http::isValidURI is too lax
|
||||
* @dataProvider provideURI
|
||||
* @covers Http::isValidURI
|
||||
*/
|
||||
public function testIsValidUri( $expect, $URI, $message = '' ) {
|
||||
$this->assertEquals(
|
||||
$expect,
|
||||
(bool)Http::isValidURI( $URI ),
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Feeds URI to test a long regular expression in Http::isValidURI
|
||||
*/
|
||||
public static function provideURI() {
|
||||
/** Format: 'boolean expectation', 'URI to test', 'Optional message' */
|
||||
return [
|
||||
[ false, '¿non sens before!! http://a', 'Allow anything before URI' ],
|
||||
|
||||
# (http|https) - only two schemes allowed
|
||||
[ true, 'http://www.example.org/' ],
|
||||
[ true, 'https://www.example.org/' ],
|
||||
[ true, 'http://www.example.org', 'URI without directory' ],
|
||||
[ true, 'http://a', 'Short name' ],
|
||||
[ true, 'http://étoile', 'Allow UTF-8 in hostname' ], # 'étoile' is french for 'star'
|
||||
[ false, '\\host\directory', 'CIFS share' ],
|
||||
[ false, 'gopher://host/dir', 'Reject gopher scheme' ],
|
||||
[ false, 'telnet://host', 'Reject telnet scheme' ],
|
||||
|
||||
# :\/\/ - double slashes
|
||||
[ false, 'http//example.org', 'Reject missing colon in protocol' ],
|
||||
[ false, 'http:/example.org', 'Reject missing slash in protocol' ],
|
||||
[ false, 'http:example.org', 'Must have two slashes' ],
|
||||
# Following fail since hostname can be made of anything
|
||||
[ false, 'http:///example.org', 'Must have exactly two slashes, not three' ],
|
||||
|
||||
# (\w+:{0,1}\w*@)? - optional user:pass
|
||||
[ true, 'http://user@host', 'Username provided' ],
|
||||
[ true, 'http://user:@host', 'Username provided, no password' ],
|
||||
[ true, 'http://user:pass@host', 'Username and password provided' ],
|
||||
|
||||
# (\S+) - host part is made of anything not whitespaces
|
||||
// commented these out in order to remove @group Broken
|
||||
// @todo are these valid tests? if so, fix Http::isValidURI so it can handle them
|
||||
// [ false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ],
|
||||
// [ false, 'http://exam:ple.org/', 'hostname can not use colons!' ],
|
||||
|
||||
# (:[0-9]+)? - port number
|
||||
[ true, 'http://example.org:80/' ],
|
||||
[ true, 'https://example.org:80/' ],
|
||||
[ true, 'http://example.org:443/' ],
|
||||
[ true, 'https://example.org:443/' ],
|
||||
|
||||
# Part after the hostname is / or / with something else
|
||||
[ true, 'http://example/#' ],
|
||||
[ true, 'http://example/!' ],
|
||||
[ true, 'http://example/:' ],
|
||||
[ true, 'http://example/.' ],
|
||||
[ true, 'http://example/?' ],
|
||||
[ true, 'http://example/+' ],
|
||||
[ true, 'http://example/=' ],
|
||||
[ true, 'http://example/&' ],
|
||||
[ true, 'http://example/%' ],
|
||||
[ true, 'http://example/@' ],
|
||||
[ true, 'http://example/-' ],
|
||||
[ true, 'http://example//' ],
|
||||
[ true, 'http://example/&' ],
|
||||
|
||||
# Fragment
|
||||
[ true, 'http://exam#ple.org', ], # This one is valid, really!
|
||||
[ true, 'http://example.org:80#anchor' ],
|
||||
[ true, 'http://example.org/?id#anchor' ],
|
||||
[ true, 'http://example.org/?#anchor' ],
|
||||
|
||||
[ false, 'http://a ¿non !!sens after', 'Allow anything after URI' ],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
258
tests/phpunit/unit/includes/session/SessionUnitTest.php
Normal file
258
tests/phpunit/unit/includes/session/SessionUnitTest.php
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
<?php
|
||||
|
||||
namespace MediaWiki\Session;
|
||||
|
||||
use Psr\Log\LogLevel;
|
||||
use MediaWikiUnitTestCase;
|
||||
use Wikimedia\TestingAccessWrapper;
|
||||
|
||||
/**
|
||||
* @group Session
|
||||
* @covers MediaWiki\Session\Session
|
||||
*/
|
||||
class SessionUnitTest extends MediaWikiUnitTestCase {
|
||||
|
||||
public function testConstructor() {
|
||||
$backend = TestUtils::getDummySessionBackend();
|
||||
TestingAccessWrapper::newFromObject( $backend )->requests = [ -1 => 'dummy' ];
|
||||
TestingAccessWrapper::newFromObject( $backend )->id = new SessionId( 'abc' );
|
||||
|
||||
$session = new Session( $backend, 42, new \TestLogger );
|
||||
$priv = TestingAccessWrapper::newFromObject( $session );
|
||||
$this->assertSame( $backend, $priv->backend );
|
||||
$this->assertSame( 42, $priv->index );
|
||||
|
||||
$request = new \FauxRequest();
|
||||
$priv2 = TestingAccessWrapper::newFromObject( $session->sessionWithRequest( $request ) );
|
||||
$this->assertSame( $backend, $priv2->backend );
|
||||
$this->assertNotSame( $priv->index, $priv2->index );
|
||||
$this->assertSame( $request, $priv2->getRequest() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMethods
|
||||
* @param string $m Method to test
|
||||
* @param array $args Arguments to pass to the method
|
||||
* @param bool $index Whether the backend method gets passed the index
|
||||
* @param bool $ret Whether the method returns a value
|
||||
*/
|
||||
public function testMethods( $m, $args, $index, $ret ) {
|
||||
$mock = $this->getMockBuilder( DummySessionBackend::class )
|
||||
->setMethods( [ $m, 'deregisterSession' ] )
|
||||
->getMock();
|
||||
$mock->expects( $this->once() )->method( 'deregisterSession' )
|
||||
->with( $this->identicalTo( 42 ) );
|
||||
|
||||
$tmp = $mock->expects( $this->once() )->method( $m );
|
||||
$expectArgs = [];
|
||||
if ( $index ) {
|
||||
$expectArgs[] = $this->identicalTo( 42 );
|
||||
}
|
||||
foreach ( $args as $arg ) {
|
||||
$expectArgs[] = $this->identicalTo( $arg );
|
||||
}
|
||||
$tmp = call_user_func_array( [ $tmp, 'with' ], $expectArgs );
|
||||
|
||||
$retval = new \stdClass;
|
||||
$tmp->will( $this->returnValue( $retval ) );
|
||||
|
||||
$session = TestUtils::getDummySession( $mock, 42 );
|
||||
|
||||
if ( $ret ) {
|
||||
$this->assertSame( $retval, call_user_func_array( [ $session, $m ], $args ) );
|
||||
} else {
|
||||
$this->assertNull( call_user_func_array( [ $session, $m ], $args ) );
|
||||
}
|
||||
|
||||
// Trigger Session destructor
|
||||
$session = null;
|
||||
}
|
||||
|
||||
public static function provideMethods() {
|
||||
return [
|
||||
[ 'getId', [], false, true ],
|
||||
[ 'getSessionId', [], false, true ],
|
||||
[ 'resetId', [], false, true ],
|
||||
[ 'getProvider', [], false, true ],
|
||||
[ 'isPersistent', [], false, true ],
|
||||
[ 'persist', [], false, false ],
|
||||
[ 'unpersist', [], false, false ],
|
||||
[ 'shouldRememberUser', [], false, true ],
|
||||
[ 'setRememberUser', [ true ], false, false ],
|
||||
[ 'getRequest', [], true, true ],
|
||||
[ 'getUser', [], false, true ],
|
||||
[ 'getAllowedUserRights', [], false, true ],
|
||||
[ 'canSetUser', [], false, true ],
|
||||
[ 'setUser', [ new \stdClass ], false, false ],
|
||||
[ 'suggestLoginUsername', [], true, true ],
|
||||
[ 'shouldForceHTTPS', [], false, true ],
|
||||
[ 'setForceHTTPS', [ true ], false, false ],
|
||||
[ 'getLoggedOutTimestamp', [], false, true ],
|
||||
[ 'setLoggedOutTimestamp', [ 123 ], false, false ],
|
||||
[ 'getProviderMetadata', [], false, true ],
|
||||
[ 'save', [], false, false ],
|
||||
[ 'delaySave', [], false, true ],
|
||||
[ 'renew', [], false, false ],
|
||||
];
|
||||
}
|
||||
|
||||
public function testDataAccess() {
|
||||
$session = TestUtils::getDummySession();
|
||||
$backend = TestingAccessWrapper::newFromObject( $session )->backend;
|
||||
|
||||
$this->assertEquals( 1, $session->get( 'foo' ) );
|
||||
$this->assertEquals( 'zero', $session->get( 0 ) );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$this->assertEquals( null, $session->get( 'null' ) );
|
||||
$this->assertEquals( 'default', $session->get( 'null', 'default' ) );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$session->set( 'foo', 55 );
|
||||
$this->assertEquals( 55, $backend->data['foo'] );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
|
||||
$session->set( 1, 'one' );
|
||||
$this->assertEquals( 'one', $backend->data[1] );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
|
||||
$session->set( 1, 'one' );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$this->assertTrue( $session->exists( 'foo' ) );
|
||||
$this->assertTrue( $session->exists( 1 ) );
|
||||
$this->assertFalse( $session->exists( 'null' ) );
|
||||
$this->assertFalse( $session->exists( 100 ) );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$session->remove( 'foo' );
|
||||
$this->assertArrayNotHasKey( 'foo', $backend->data );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
$session->remove( 1 );
|
||||
$this->assertArrayNotHasKey( 1, $backend->data );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
|
||||
$session->remove( 101 );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$backend->data = [ 'a', 'b', '?' => 'c' ];
|
||||
$this->assertSame( 3, $session->count() );
|
||||
$this->assertSame( 3, count( $session ) );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$data = [];
|
||||
foreach ( $session as $key => $value ) {
|
||||
$data[$key] = $value;
|
||||
}
|
||||
$this->assertEquals( $backend->data, $data );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$this->assertEquals( $backend->data, iterator_to_array( $session ) );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
}
|
||||
|
||||
public function testArrayAccess() {
|
||||
$logger = new \TestLogger;
|
||||
$session = TestUtils::getDummySession( null, -1, $logger );
|
||||
$backend = TestingAccessWrapper::newFromObject( $session )->backend;
|
||||
|
||||
$this->assertEquals( 1, $session['foo'] );
|
||||
$this->assertEquals( 'zero', $session[0] );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$logger->setCollect( true );
|
||||
$this->assertEquals( null, $session['null'] );
|
||||
$logger->setCollect( false );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
$this->assertSame( [
|
||||
[ LogLevel::DEBUG, 'Undefined index (auto-adds to session with a null value): null' ]
|
||||
], $logger->getBuffer() );
|
||||
$logger->clearBuffer();
|
||||
|
||||
$session['foo'] = 55;
|
||||
$this->assertEquals( 55, $backend->data['foo'] );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
|
||||
$session[1] = 'one';
|
||||
$this->assertEquals( 'one', $backend->data[1] );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
|
||||
$session[1] = 'one';
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
$session['bar'] = [ 'baz' => [] ];
|
||||
$session['bar']['baz']['quux'] = 2;
|
||||
$this->assertEquals( [ 'baz' => [ 'quux' => 2 ] ], $backend->data['bar'] );
|
||||
|
||||
$logger->setCollect( true );
|
||||
$session['bar2']['baz']['quux'] = 3;
|
||||
$logger->setCollect( false );
|
||||
$this->assertEquals( [ 'baz' => [ 'quux' => 3 ] ], $backend->data['bar2'] );
|
||||
$this->assertSame( [
|
||||
[ LogLevel::DEBUG, 'Undefined index (auto-adds to session with a null value): bar2' ]
|
||||
], $logger->getBuffer() );
|
||||
$logger->clearBuffer();
|
||||
|
||||
$backend->dirty = false;
|
||||
$this->assertTrue( isset( $session['foo'] ) );
|
||||
$this->assertTrue( isset( $session[1] ) );
|
||||
$this->assertFalse( isset( $session['null'] ) );
|
||||
$this->assertFalse( isset( $session['missing'] ) );
|
||||
$this->assertFalse( isset( $session[100] ) );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
|
||||
unset( $session['foo'] );
|
||||
$this->assertArrayNotHasKey( 'foo', $backend->data );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
unset( $session[1] );
|
||||
$this->assertArrayNotHasKey( 1, $backend->data );
|
||||
$this->assertTrue( $backend->dirty );
|
||||
$backend->dirty = false;
|
||||
|
||||
unset( $session[101] );
|
||||
$this->assertFalse( $backend->dirty );
|
||||
}
|
||||
|
||||
public function testTokens() {
|
||||
$session = TestUtils::getDummySession();
|
||||
$priv = TestingAccessWrapper::newFromObject( $session );
|
||||
$backend = $priv->backend;
|
||||
|
||||
$token = TestingAccessWrapper::newFromObject( $session->getToken() );
|
||||
$this->assertArrayHasKey( 'wsTokenSecrets', $backend->data );
|
||||
$this->assertArrayHasKey( 'default', $backend->data['wsTokenSecrets'] );
|
||||
$secret = $backend->data['wsTokenSecrets']['default'];
|
||||
$this->assertSame( $secret, $token->secret );
|
||||
$this->assertSame( '', $token->salt );
|
||||
$this->assertTrue( $token->wasNew() );
|
||||
|
||||
$token = TestingAccessWrapper::newFromObject( $session->getToken( 'foo' ) );
|
||||
$this->assertSame( $secret, $token->secret );
|
||||
$this->assertSame( 'foo', $token->salt );
|
||||
$this->assertFalse( $token->wasNew() );
|
||||
|
||||
$backend->data['wsTokenSecrets']['secret'] = 'sekret';
|
||||
$token = TestingAccessWrapper::newFromObject(
|
||||
$session->getToken( [ 'bar', 'baz' ], 'secret' )
|
||||
);
|
||||
$this->assertSame( 'sekret', $token->secret );
|
||||
$this->assertSame( 'bar|baz', $token->salt );
|
||||
$this->assertFalse( $token->wasNew() );
|
||||
|
||||
$session->resetToken( 'secret' );
|
||||
$this->assertArrayHasKey( 'wsTokenSecrets', $backend->data );
|
||||
$this->assertArrayHasKey( 'default', $backend->data['wsTokenSecrets'] );
|
||||
$this->assertArrayNotHasKey( 'secret', $backend->data['wsTokenSecrets'] );
|
||||
|
||||
$session->resetAllTokens();
|
||||
$this->assertArrayNotHasKey( 'wsTokenSecrets', $backend->data );
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue