diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Core/Controller/OCSControllerTest.php | 49 | ||||
-rw-r--r-- | tests/Settings/Controller/UsersControllerTest.php | 82 | ||||
-rw-r--r-- | tests/lib/Accounts/AccountsManagerTest.php | 202 | ||||
-rw-r--r-- | tests/lib/App/ManagerTest.php | 4 | ||||
-rw-r--r-- | tests/lib/AppTest.php | 9 | ||||
-rw-r--r-- | tests/lib/Security/IdentityProof/ManagerTest.php | 166 |
6 files changed, 429 insertions, 83 deletions
diff --git a/tests/Core/Controller/OCSControllerTest.php b/tests/Core/Controller/OCSControllerTest.php index 38356483c95..6c47521786f 100644 --- a/tests/Core/Controller/OCSControllerTest.php +++ b/tests/Core/Controller/OCSControllerTest.php @@ -24,6 +24,8 @@ namespace OC\Core\Controller; use OC\CapabilitiesManager; use OC\Security\Bruteforce\Throttler; +use OC\Security\IdentityProof\Key; +use OC\Security\IdentityProof\Manager; use OCP\AppFramework\Http\DataResponse; use OCP\IRequest; use OCP\IUser; @@ -32,22 +34,18 @@ use OCP\IUserSession; use Test\TestCase; class OCSControllerTest extends TestCase { - /** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */ private $request; - /** @var CapabilitiesManager|\PHPUnit_Framework_MockObject_MockObject */ private $capabilitiesManager; - /** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */ private $userSession; - /** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */ private $userManager; - /** @var Throttler|\PHPUnit_Framework_MockObject_MockObject */ private $throttler; - + /** @var Manager|\PHPUnit_Framework_MockObject_MockObject */ + private $keyManager; /** @var OCSController */ private $controller; @@ -59,6 +57,7 @@ class OCSControllerTest extends TestCase { $this->userSession = $this->createMock(IUserSession::class); $this->userManager = $this->createMock(IUserManager::class); $this->throttler = $this->createMock(Throttler::class); + $this->keyManager = $this->createMock(Manager::class); $this->controller = new OCSController( 'core', @@ -66,7 +65,8 @@ class OCSControllerTest extends TestCase { $this->capabilitiesManager, $this->userSession, $this->userManager, - $this->throttler + $this->throttler, + $this->keyManager ); } @@ -206,4 +206,39 @@ class OCSControllerTest extends TestCase { $this->assertEquals($expected, $this->controller->personCheck('', '')); } + + public function testGetIdentityProofWithNotExistingUser() { + $this->userManager + ->expects($this->once()) + ->method('get') + ->with('NotExistingUser') + ->willReturn(null); + + $expected = new DataResponse('User not found', 404); + $this->assertEquals($expected, $this->controller->getIdentityProof('NotExistingUser')); + } + + public function testGetIdentityProof() { + $user = $this->createMock(IUser::class); + $key = $this->createMock(Key::class); + $this->userManager + ->expects($this->once()) + ->method('get') + ->with('ExistingUser') + ->willReturn($user); + $this->keyManager + ->expects($this->once()) + ->method('getKey') + ->with($user) + ->willReturn($key); + $key + ->expects($this->once()) + ->method('getPublic') + ->willReturn('Existing Users public key'); + + $expected = new DataResponse([ + 'public' => 'Existing Users public key', + ]); + $this->assertEquals($expected, $this->controller->getIdentityProof('ExistingUser')); + } } diff --git a/tests/Settings/Controller/UsersControllerTest.php b/tests/Settings/Controller/UsersControllerTest.php index 03c3a2e2ab4..ec92479b40e 100644 --- a/tests/Settings/Controller/UsersControllerTest.php +++ b/tests/Settings/Controller/UsersControllerTest.php @@ -10,6 +10,7 @@ namespace Tests\Settings\Controller; +use OC\Accounts\AccountManager; use OC\Group\Manager; use OC\Settings\Controller\UsersController; use OCP\App\IAppManager; @@ -57,6 +58,8 @@ class UsersControllerTest extends \Test\TestCase { private $avatarManager; /** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */ private $l; + /** @var AccountManager | \PHPUnit_Framework_MockObject_MockObject */ + private $accountManager; protected function setUp() { parent::setUp(); @@ -71,6 +74,7 @@ class UsersControllerTest extends \Test\TestCase { $this->urlGenerator = $this->createMock(IURLGenerator::class); $this->appManager = $this->createMock(IAppManager::class); $this->avatarManager = $this->createMock(IAvatarManager::class); + $this->accountManager = $this->createMock(AccountManager::class); $this->l = $this->createMock(IL10N::class); $this->l->method('t') ->will($this->returnCallback(function ($text, $parameters = []) { @@ -117,7 +121,8 @@ class UsersControllerTest extends \Test\TestCase { 'no-reply@owncloud.com', $this->urlGenerator, $this->appManager, - $this->avatarManager + $this->avatarManager, + $this->accountManager ); } @@ -1760,74 +1765,6 @@ class UsersControllerTest extends \Test\TestCase { $this->assertEquals($expectedResult, $result); } - /** - * @return array - */ - public function setEmailAddressData() { - return [ - /* mailAddress, isValid, expectsUpdate, canChangeDisplayName, responseCode */ - [ '', true, true, true, Http::STATUS_OK ], - [ 'foo@local', true, true, true, Http::STATUS_OK], - [ 'foo@bar@local', false, false, true, Http::STATUS_UNPROCESSABLE_ENTITY], - [ 'foo@local', true, false, false, Http::STATUS_FORBIDDEN], - ]; - } - - /** - * @dataProvider setEmailAddressData - * - * @param string $mailAddress - * @param bool $isValid - * @param bool $expectsUpdate - * @param bool $expectsDelete - */ - public function testSetEmailAddress($mailAddress, $isValid, $expectsUpdate, $canChangeDisplayName, $responseCode) { - $controller = $this->getController(true); - - $user = $this->getMockBuilder('\OC\User\User') - ->disableOriginalConstructor()->getMock(); - $user - ->expects($this->any()) - ->method('getUID') - ->will($this->returnValue('foo')); - $user - ->expects($this->any()) - ->method('canChangeDisplayName') - ->will($this->returnValue($canChangeDisplayName)); - $user - ->expects($expectsUpdate ? $this->once() : $this->never()) - ->method('setEMailAddress') - ->with( - $this->equalTo($mailAddress) - ); - - $this->userSession - ->expects($this->atLeastOnce()) - ->method('getUser') - ->will($this->returnValue($user)); - $this->mailer - ->expects($this->any()) - ->method('validateMailAddress') - ->with($mailAddress) - ->willReturn($isValid); - - if ($isValid) { - $user->expects($this->atLeastOnce()) - ->method('canChangeDisplayName') - ->willReturn(true); - - $this->userManager - ->expects($this->atLeastOnce()) - ->method('get') - ->with('foo') - ->will($this->returnValue($user)); - } - - $response = $controller->setMailAddress($user->getUID(), $mailAddress); - - $this->assertSame($responseCode, $response->getStatus()); - } - public function testStatsAdmin() { $controller = $this->getController(true); @@ -1976,6 +1913,7 @@ class UsersControllerTest extends \Test\TestCase { ->method('get') ->with($editUser->getUID()) ->willReturn($editUser); + $this->accountManager->expects($this->any())->method('getUser')->willReturn([]); $subadmin = $this->getMockBuilder('\OC\SubAdmin') ->disableOriginalConstructor() @@ -1994,10 +1932,6 @@ class UsersControllerTest extends \Test\TestCase { ->willReturn($isAdmin); if ($valid === true) { - $editUser->expects($this->once()) - ->method('setDisplayName') - ->with('newDisplayName') - ->willReturn(true); $expectedResponse = new DataResponse( [ 'status' => 'success', @@ -2009,7 +1943,6 @@ class UsersControllerTest extends \Test\TestCase { ] ); } else { - $editUser->expects($this->never())->method('setDisplayName'); $expectedResponse = new DataResponse( [ 'status' => 'error', @@ -2040,6 +1973,7 @@ class UsersControllerTest extends \Test\TestCase { ->expects($this->once()) ->method('getUser') ->willReturn($user); + $this->userManager ->expects($this->once()) ->method('get') diff --git a/tests/lib/Accounts/AccountsManagerTest.php b/tests/lib/Accounts/AccountsManagerTest.php new file mode 100644 index 00000000000..de88fbcab97 --- /dev/null +++ b/tests/lib/Accounts/AccountsManagerTest.php @@ -0,0 +1,202 @@ +<?php +/** + * @author Björn Schießle <schiessle@owncloud.com> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + + +namespace Test\Accounts; + + +use OC\Accounts\AccountManager; +use OC\Mail\Mailer; +use OCP\IUser; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Test\TestCase; + +/** + * Class AccountsManagerTest + * + * @group DB + * @package Test\Accounts + */ +class AccountsManagerTest extends TestCase { + + /** @var \OCP\IDBConnection */ + private $connection; + + /** @var EventDispatcherInterface | \PHPUnit_Framework_MockObject_MockObject */ + private $eventDispatcher; + + /** @var string accounts table name */ + private $table = 'accounts'; + + public function setUp() { + parent::setUp(); + $this->eventDispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface') + ->disableOriginalConstructor()->getMock(); + $this->connection = \OC::$server->getDatabaseConnection(); + } + + public function tearDown() { + parent::tearDown(); + $query = $this->connection->getQueryBuilder(); + $query->delete($this->table)->execute(); + } + + /** + * get a instance of the accountManager + * + * @param array $mockedMethods list of methods which should be mocked + * @return \PHPUnit_Framework_MockObject_MockObject | AccountManager + */ + public function getInstance($mockedMethods = null) { + return $this->getMockBuilder('OC\Accounts\AccountManager') + ->setConstructorArgs([$this->connection, $this->eventDispatcher]) + ->setMethods($mockedMethods) + ->getMock(); + + } + + /** + * @dataProvider dataTrueFalse + * + * @param bool $userAlreadyExists + */ + public function testUpdateUser($userAlreadyExists) { + $accountManager = $this->getInstance(['getUser', 'insertNewUser', 'updateExistingUser']); + $user = $this->getMockBuilder('OCP\IUser')->getMock(); + + $accountManager->expects($this->once())->method('getUser')->with($user)->willReturn($userAlreadyExists); + + if ($userAlreadyExists) { + $accountManager->expects($this->once())->method('updateExistingUser') + ->with($user, 'data'); + $accountManager->expects($this->never())->method('insertNewUser'); + } else { + $accountManager->expects($this->once())->method('insertNewUser') + ->with($user, 'data'); + $accountManager->expects($this->never())->method('updateExistingUser'); + } + + $this->eventDispatcher->expects($this->once())->method('dispatch') + ->willReturnCallback(function($eventName, $event) use ($user) { + $this->assertSame('OC\AccountManager::userUpdated', $eventName); + $this->assertInstanceOf('Symfony\Component\EventDispatcher\GenericEvent', $event); + } + ); + + $accountManager->updateUser($user, 'data'); + } + + public function dataTrueFalse() { + return [ + [true], + [false] + ]; + } + + + /** + * @dataProvider dataTestGetUser + * + * @param string $setUser + * @param array $setData + * @param IUser $askUser + * @param array $expectedData + * @param book $userAlreadyExists + */ + public function testGetUser($setUser, $setData, $askUser, $expectedData, $userAlreadyExists) { + $accountManager = $this->getInstance(['buildDefaultUserRecord', 'insertNewUser']); + if (!$userAlreadyExists) { + $accountManager->expects($this->once())->method('buildDefaultUserRecord') + ->with($askUser)->willReturn($expectedData); + $accountManager->expects($this->once())->method('insertNewUser') + ->with($askUser, $expectedData); + } + $this->addDummyValuesToTable($setUser, $setData); + $this->assertEquals($expectedData, + $accountManager->getUser($askUser) + ); + } + + public function dataTestGetUser() { + $user1 = $this->getMockBuilder('OCP\IUser')->getMock(); + $user1->expects($this->any())->method('getUID')->willReturn('user1'); + $user2 = $this->getMockBuilder('OCP\IUser')->getMock(); + $user2->expects($this->any())->method('getUID')->willReturn('user2'); + return [ + ['user1', ['key' => 'value'], $user1, ['key' => 'value'], true], + ['user1', ['key' => 'value'], $user2, [], false], + ]; + } + + public function testUpdateExistingUser() { + $user = $this->getMockBuilder('OCP\IUser')->getMock(); + $user->expects($this->once())->method('getUID')->willReturn('uid'); + $oldData = ['key' => 'value']; + $newData = ['newKey' => 'newValue']; + + $accountManager = $this->getInstance(); + $this->addDummyValuesToTable('uid', $oldData); + $this->invokePrivate($accountManager, 'updateExistingUser', [$user, $newData]); + $newDataFromTable = $this->getDataFromTable('uid'); + $this->assertEquals($newData, $newDataFromTable); + } + + public function testInsertNewUser() { + $user = $this->getMockBuilder('OCP\IUser')->getMock(); + $uid = 'uid'; + $data = ['key' => 'value']; + + $accountManager = $this->getInstance(); + $user->expects($this->once())->method('getUID')->willReturn($uid); + $this->assertNull($this->getDataFromTable($uid)); + $this->invokePrivate($accountManager, 'insertNewUser', [$user, $data]); + + $dataFromDb = $this->getDataFromTable($uid); + $this->assertEquals($data, $dataFromDb); + } + + private function addDummyValuesToTable($uid, $data) { + + $query = $this->connection->getQueryBuilder(); + $query->insert($this->table) + ->values( + [ + 'uid' => $query->createNamedParameter($uid), + 'data' => $query->createNamedParameter(json_encode($data)), + ] + ) + ->execute(); + } + + private function getDataFromTable($uid) { + $query = $this->connection->getQueryBuilder(); + $query->select('data')->from($this->table) + ->where($query->expr()->eq('uid', $query->createParameter('uid'))) + ->setParameter('uid', $uid); + $query->execute(); + $result = $query->execute()->fetchAll(); + + if (!empty($result)) { + return json_decode($result[0]['data'], true); + } + } + +} diff --git a/tests/lib/App/ManagerTest.php b/tests/lib/App/ManagerTest.php index 3dbcb8a5609..e38f72b3d92 100644 --- a/tests/lib/App/ManagerTest.php +++ b/tests/lib/App/ManagerTest.php @@ -320,6 +320,7 @@ class ManagerTest extends TestCase { 'dav', 'federatedfilesharing', 'files', + 'lookup_server_connector', 'provisioning_api', 'test1', 'test3', @@ -344,6 +345,7 @@ class ManagerTest extends TestCase { 'dav', 'federatedfilesharing', 'files', + 'lookup_server_connector', 'provisioning_api', 'test1', 'test3', @@ -364,6 +366,7 @@ class ManagerTest extends TestCase { 'files' => ['id' => 'files'], 'federatedfilesharing' => ['id' => 'federatedfilesharing'], 'provisioning_api' => ['id' => 'provisioning_api'], + 'lookup_server_connector' => ['id' => 'lookup_server_connector'], 'test1' => ['id' => 'test1', 'version' => '1.0.1', 'requiremax' => '9.0.0'], 'test2' => ['id' => 'test2', 'version' => '1.0.0', 'requiremin' => '8.2.0'], 'test3' => ['id' => 'test3', 'version' => '1.2.4', 'requiremin' => '9.0.0'], @@ -408,6 +411,7 @@ class ManagerTest extends TestCase { 'files' => ['id' => 'files'], 'federatedfilesharing' => ['id' => 'federatedfilesharing'], 'provisioning_api' => ['id' => 'provisioning_api'], + 'lookup_server_connector' => ['id' => 'lookup_server_connector'], 'test1' => ['id' => 'test1', 'version' => '1.0.1', 'requiremax' => '8.0.0'], 'test2' => ['id' => 'test2', 'version' => '1.0.0', 'requiremin' => '8.2.0'], 'test3' => ['id' => 'test3', 'version' => '1.2.4', 'requiremin' => '9.0.0'], diff --git a/tests/lib/AppTest.php b/tests/lib/AppTest.php index 971d86cf6a4..575e32dd60c 100644 --- a/tests/lib/AppTest.php +++ b/tests/lib/AppTest.php @@ -351,6 +351,7 @@ class AppTest extends \Test\TestCase { 'appforgroup12', 'dav', 'federatedfilesharing', + 'lookup_server_connector', 'provisioning_api', 'twofactor_backupcodes', 'workflowengine', @@ -368,6 +369,7 @@ class AppTest extends \Test\TestCase { 'appforgroup2', 'dav', 'federatedfilesharing', + 'lookup_server_connector', 'provisioning_api', 'twofactor_backupcodes', 'workflowengine', @@ -386,6 +388,7 @@ class AppTest extends \Test\TestCase { 'appforgroup2', 'dav', 'federatedfilesharing', + 'lookup_server_connector', 'provisioning_api', 'twofactor_backupcodes', 'workflowengine', @@ -404,6 +407,7 @@ class AppTest extends \Test\TestCase { 'appforgroup2', 'dav', 'federatedfilesharing', + 'lookup_server_connector', 'provisioning_api', 'twofactor_backupcodes', 'workflowengine', @@ -422,6 +426,7 @@ class AppTest extends \Test\TestCase { 'appforgroup2', 'dav', 'federatedfilesharing', + 'lookup_server_connector', 'provisioning_api', 'twofactor_backupcodes', 'workflowengine', @@ -502,11 +507,11 @@ class AppTest extends \Test\TestCase { ); $apps = \OC_App::getEnabledApps(); - $this->assertEquals(array('files', 'app3', 'dav', 'federatedfilesharing', 'provisioning_api', 'twofactor_backupcodes', 'workflowengine'), $apps); + $this->assertEquals(array('files', 'app3', 'dav', 'federatedfilesharing', 'lookup_server_connector', 'provisioning_api', 'twofactor_backupcodes', 'workflowengine'), $apps); // mock should not be called again here $apps = \OC_App::getEnabledApps(); - $this->assertEquals(array('files', 'app3', 'dav', 'federatedfilesharing', 'provisioning_api', 'twofactor_backupcodes', 'workflowengine'), $apps); + $this->assertEquals(array('files', 'app3', 'dav', 'federatedfilesharing', 'lookup_server_connector', 'provisioning_api', 'twofactor_backupcodes', 'workflowengine'), $apps); $this->restoreAppConfig(); \OC_User::setUserId(null); diff --git a/tests/lib/Security/IdentityProof/ManagerTest.php b/tests/lib/Security/IdentityProof/ManagerTest.php new file mode 100644 index 00000000000..d93f675825b --- /dev/null +++ b/tests/lib/Security/IdentityProof/ManagerTest.php @@ -0,0 +1,166 @@ +<?php +/** + * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace Test\Security; + +use OC\Security\IdentityProof\Key; +use OC\Security\IdentityProof\Manager; +use OCP\Files\IAppData; +use OCP\Files\SimpleFS\ISimpleFile; +use OCP\Files\SimpleFS\ISimpleFolder; +use OCP\IUser; +use OCP\Security\ICrypto; +use Test\TestCase; + +class ManagerTest extends TestCase { + /** @var IAppData|\PHPUnit_Framework_MockObject_MockObject */ + private $appData; + /** @var ICrypto|\PHPUnit_Framework_MockObject_MockObject */ + private $crypto; + /** @var Manager|\PHPUnit_Framework_MockObject_MockObject */ + private $manager; + + public function setUp() { + parent::setUp(); + $this->appData = $this->createMock(IAppData::class); + $this->crypto = $this->createMock(ICrypto::class); + $this->manager = $this->getMockBuilder(Manager::class) + ->setConstructorArgs([ + $this->appData, + $this->crypto + ]) + ->setMethods(['generateKeyPair']) + ->getMock(); + } + + public function testGetKeyWithExistingKey() { + $user = $this->createMock(IUser::class); + $user + ->expects($this->once()) + ->method('getUID') + ->willReturn('MyUid'); + $folder = $this->createMock(ISimpleFolder::class); + $privateFile = $this->createMock(ISimpleFile::class); + $privateFile + ->expects($this->once()) + ->method('getContent') + ->willReturn('EncryptedPrivateKey'); + $publicFile = $this->createMock(ISimpleFile::class); + $publicFile + ->expects($this->once()) + ->method('getContent') + ->willReturn('MyPublicKey'); + $this->crypto + ->expects($this->once()) + ->method('decrypt') + ->with('EncryptedPrivateKey') + ->willReturn('MyPrivateKey'); + $folder + ->expects($this->at(0)) + ->method('getFile') + ->with('private') + ->willReturn($privateFile); + $folder + ->expects($this->at(1)) + ->method('getFile') + ->with('public') + ->willReturn($publicFile); + $this->appData + ->expects($this->once()) + ->method('getFolder') + ->with('MyUid') + ->willReturn($folder); + + $expected = new Key('MyPublicKey', 'MyPrivateKey'); + $this->assertEquals($expected, $this->manager->getKey($user)); + } + + public function testGetKeyWithNotExistingKey() { + $user = $this->createMock(IUser::class); + $user + ->expects($this->exactly(3)) + ->method('getUID') + ->willReturn('MyUid'); + $this->appData + ->expects($this->at(0)) + ->method('getFolder') + ->with('MyUid') + ->willThrowException(new \Exception()); + $this->manager + ->expects($this->once()) + ->method('generateKeyPair') + ->willReturn(['MyNewPublicKey', 'MyNewPrivateKey']); + $this->appData + ->expects($this->at(1)) + ->method('newFolder') + ->with('MyUid'); + $folder = $this->createMock(ISimpleFolder::class); + $this->crypto + ->expects($this->once()) + ->method('encrypt') + ->with('MyNewPrivateKey') + ->willReturn('MyNewEncryptedPrivateKey'); + $privateFile = $this->createMock(ISimpleFile::class); + $privateFile + ->expects($this->once()) + ->method('putContent') + ->with('MyNewEncryptedPrivateKey'); + $publicFile = $this->createMock(ISimpleFile::class); + $publicFile + ->expects($this->once()) + ->method('putContent') + ->with('MyNewPublicKey'); + $folder + ->expects($this->at(0)) + ->method('newFile') + ->with('private') + ->willReturn($privateFile); + $folder + ->expects($this->at(1)) + ->method('newFile') + ->with('public') + ->willReturn($publicFile); + $this->appData + ->expects($this->at(2)) + ->method('getFolder') + ->with('MyUid') + ->willReturn($folder); + + + $expected = new Key('MyNewPublicKey', 'MyNewPrivateKey'); + $this->assertEquals($expected, $this->manager->getKey($user)); + } + + public function testGenerateKeyPair() { + $manager = new Manager( + $this->appData, + $this->crypto + ); + $data = 'MyTestData'; + + list($resultPublicKey, $resultPrivateKey) = $this->invokePrivate($manager, 'generateKeyPair'); + openssl_sign($data, $signature, $resultPrivateKey); + $details = openssl_pkey_get_details(openssl_pkey_get_public($resultPublicKey)); + + $this->assertSame(1, openssl_verify($data, $signature, $resultPublicKey)); + $this->assertSame(2048, $details['bits']); + } +} |