From 9e7a95fe58ee8ace0ae30ff2ebda993018542187 Mon Sep 17 00:00:00 2001
From: Roeland Jago Douma <roeland@famdouma.nl>
Date: Thu, 31 May 2018 22:56:26 +0200
Subject: [PATCH] Add more tests

* Add a lot of tests
* Fixes related to those tests
* Fix tests

Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
---
 lib/private/Authentication/Token/Manager.php  |  12 +-
 .../Token/PublicKeyTokenMapper.php            |   2 +
 .../Token/PublicKeyTokenProvider.php          |   3 +-
 .../Token/DefaultTokenCleanupJobTest.php      |  12 +-
 .../lib/Authentication/Token/ManagerTest.php  | 451 ++++++++++++++++++
 .../Token/PublicKeyTokenMapperTest.php        |  26 +-
 .../Token/PublicKeyTokenProviderTest.php      |  34 +-
 7 files changed, 506 insertions(+), 34 deletions(-)
 create mode 100644 tests/lib/Authentication/Token/ManagerTest.php

diff --git a/lib/private/Authentication/Token/Manager.php b/lib/private/Authentication/Token/Manager.php
index e4f0ead862b..5e30afbc92e 100644
--- a/lib/private/Authentication/Token/Manager.php
+++ b/lib/private/Authentication/Token/Manager.php
@@ -144,7 +144,7 @@ class Manager implements IProvider {
 	 */
 	public function getTokenById(int $tokenId): IToken {
 		try {
-			$this->publicKeyTokenProvider->getTokenById($tokenId);
+			return $this->publicKeyTokenProvider->getTokenById($tokenId);
 		} catch (InvalidTokenException $e) {
 			return $this->defaultTokenProvider->getTokenById($tokenId);
 		}
@@ -178,16 +178,22 @@ class Manager implements IProvider {
 		if ($savedToken instanceof PublicKeyToken) {
 			return $this->publicKeyTokenProvider->getPassword($savedToken, $tokenId);
 		}
+
+		throw new InvalidTokenException();
 	}
 
 	public function setPassword(IToken $token, string $tokenId, string $password) {
 		if ($token instanceof DefaultToken) {
 			$this->defaultTokenProvider->setPassword($token, $tokenId, $password);
+			return;
 		}
 
-		if ($tokenId instanceof PublicKeyToken) {
+		if ($token instanceof PublicKeyToken) {
 			$this->publicKeyTokenProvider->setPassword($token, $tokenId, $password);
+			return;
 		}
+
+		throw new InvalidTokenException();
 	}
 
 	public function invalidateToken(string $token) {
@@ -219,6 +225,8 @@ class Manager implements IProvider {
 		if ($token instanceof PublicKeyToken) {
 			return $this->publicKeyTokenProvider->rotate($token, $oldTokenId, $newTokenId);
 		}
+
+		throw new InvalidTokenException();
 	}
 
 
diff --git a/lib/private/Authentication/Token/PublicKeyTokenMapper.php b/lib/private/Authentication/Token/PublicKeyTokenMapper.php
index 30349fba31a..23982c6ba09 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenMapper.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenMapper.php
@@ -166,5 +166,7 @@ class PublicKeyTokenMapper extends QBMapper {
 			->where($qb->expr()->eq('type', $qb->createNamedParameter(IToken::TEMPORARY_TOKEN)))
 			->andWhere($qb->expr()->neq('id', $qb->createNamedParameter($except->getId())))
 			->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(2, IQueryBuilder::PARAM_INT)));
+
+		$qb->execute();
 	}
 }
diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
index e512133a962..ca7a7e37e1e 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
@@ -196,7 +196,7 @@ class PublicKeyTokenProvider implements IProvider {
 		// Update the password for all tokens
 		$tokens = $this->mapper->getTokenByUser($token->getUID());
 		foreach ($tokens as $t) {
-			$publicKey = $token->getPublicKey();
+			$publicKey = $t->getPublicKey();
 			$t->setPassword($this->encryptPassword($password, $publicKey));
 			$this->updateToken($t);
 		}
@@ -271,6 +271,7 @@ class PublicKeyTokenProvider implements IProvider {
 			$defaultToken->getRemember()
 		);
 
+		$pkToken->setExpires($defaultToken->getExpires());
 		$pkToken->setId($defaultToken->getId());
 
 		return $this->mapper->update($pkToken);
diff --git a/tests/lib/Authentication/Token/DefaultTokenCleanupJobTest.php b/tests/lib/Authentication/Token/DefaultTokenCleanupJobTest.php
index c9082c08b30..b8074d75b30 100644
--- a/tests/lib/Authentication/Token/DefaultTokenCleanupJobTest.php
+++ b/tests/lib/Authentication/Token/DefaultTokenCleanupJobTest.php
@@ -23,6 +23,8 @@
 namespace Test\Authentication\Token;
 
 use OC\Authentication\Token\DefaultTokenCleanupJob;
+use OC\Authentication\Token\IProvider;
+use OC\Authentication\Token\Manager;
 use Test\TestCase;
 
 class DefaultTokenCleanupJobTest extends TestCase {
@@ -34,19 +36,13 @@ class DefaultTokenCleanupJobTest extends TestCase {
 	protected function setUp() {
 		parent::setUp();
 
-		$this->tokenProvider = $this->getMockBuilder('\OC\Authentication\Token\DefaultTokenProvider')
+		$this->tokenProvider = $this->getMockBuilder(Manager::class)
 			->disableOriginalConstructor()
 			->getMock();
-		$this->overwriteService('\OC\Authentication\Token\DefaultTokenProvider', $this->tokenProvider);
+		$this->overwriteService(IProvider::class, $this->tokenProvider);
 		$this->job = new DefaultTokenCleanupJob();
 	}
 
-	protected function tearDown() {
-		parent::tearDown();
-
-		$this->restoreService('\OC\Authentication\Token\DefaultTokenProvider');
-	}
-
 	public function testRun() {
 		$this->tokenProvider->expects($this->once())
 			->method('invalidateOldTokens')
diff --git a/tests/lib/Authentication/Token/ManagerTest.php b/tests/lib/Authentication/Token/ManagerTest.php
new file mode 100644
index 00000000000..8b77bfc4994
--- /dev/null
+++ b/tests/lib/Authentication/Token/ManagerTest.php
@@ -0,0 +1,451 @@
+<?php
+/**
+ * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @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\Authentication\Token;
+
+use OC\Authentication\Exceptions\InvalidTokenException;
+use OC\Authentication\Exceptions\PasswordlessTokenException;
+use OC\Authentication\Token\DefaultToken;
+use OC\Authentication\Token\DefaultTokenProvider;
+use OC\Authentication\Token\Manager;
+use OC\Authentication\Token\PublicKeyToken;
+use OC\Authentication\Token\PublicKeyTokenMapper;
+use OC\Authentication\Token\PublicKeyTokenProvider;
+use OC\Authentication\Token\ExpiredTokenException;
+use OC\Authentication\Token\IToken;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\IConfig;
+use OCP\ILogger;
+use OCP\IUser;
+use OCP\Security\ICrypto;
+use Test\TestCase;
+
+class ManagerTest extends TestCase {
+
+	/** @var PublicKeyTokenProvider|\PHPUnit_Framework_MockObject_MockObject */
+	private $publicKeyTokenProvider;
+	/** @var DefaultTokenProvider|\PHPUnit_Framework_MockObject_MockObject */
+	private $defaultTokenProvider;
+	/** @var Manager */
+	private $manager;
+
+	protected function setUp() {
+		parent::setUp();
+
+		$this->publicKeyTokenProvider = $this->createMock(PublicKeyTokenProvider::class);
+		$this->defaultTokenProvider = $this->createMock(DefaultTokenProvider::class);
+		$this->manager = new Manager(
+			$this->defaultTokenProvider,
+			$this->publicKeyTokenProvider
+		);
+	}
+
+	public function testGenerateToken() {
+		$this->defaultTokenProvider->expects($this->never())
+			->method('generateToken');
+
+		$token = new PublicKeyToken();
+
+		$this->publicKeyTokenProvider->expects($this->once())
+			->method('generateToken')
+			->with(
+				'token',
+				'uid',
+				'loginName',
+				'password',
+				'name',
+				IToken::TEMPORARY_TOKEN,
+				IToken::REMEMBER
+			)->willReturn($token);
+
+		$actual = $this->manager->generateToken(
+			'token',
+			'uid',
+			'loginName',
+			'password',
+			'name',
+			IToken::TEMPORARY_TOKEN,
+			IToken::REMEMBER
+		);
+
+		$this->assertSame($token, $actual);
+	}
+
+	public function tokenData(): array {
+		return [
+			[new DefaultToken()],
+			[new PublicKeyToken()],
+			[$this->createMock(IToken::class)],
+		];
+	}
+
+	protected function setNoCall(IToken $token) {
+		if (!($token instanceof DefaultToken)) {
+			$this->defaultTokenProvider->expects($this->never())
+				->method($this->anything());
+		}
+
+		if (!($token instanceof PublicKeyToken)) {
+			$this->publicKeyTokenProvider->expects($this->never())
+				->method($this->anything());
+		}
+	}
+
+	protected function setCall(IToken $token, string $function, $return = null) {
+		if ($token instanceof DefaultToken) {
+			$this->defaultTokenProvider->expects($this->once())
+				->method($function)
+				->with($token)
+				->willReturn($return);
+		}
+
+		if ($token instanceof PublicKeyToken) {
+			$this->publicKeyTokenProvider->expects($this->once())
+				->method($function)
+				->with($token)
+				->willReturn($return);
+		}
+	}
+
+	protected function setException(IToken $token) {
+		if (!($token instanceof DefaultToken) && !($token instanceof PublicKeyToken)) {
+			$this->expectException(InvalidTokenException::class);
+		}
+	}
+
+	/**
+	 * @dataProvider tokenData
+	 */
+	public function testUpdateToken(IToken $token) {
+		$this->setNoCall($token);
+		$this->setCall($token, 'updateToken');
+		$this->setException($token);
+
+		$this->manager->updateToken($token);
+	}
+
+	/**
+	 * @dataProvider tokenData
+	 */
+	public function testUpdateTokenActivity(IToken $token) {
+		$this->setNoCall($token);
+		$this->setCall($token, 'updateTokenActivity');
+		$this->setException($token);
+
+		$this->manager->updateTokenActivity($token);
+	}
+
+	/**
+	 * @dataProvider tokenData
+	 */
+	public function testGetPassword(IToken $token) {
+		$this->setNoCall($token);
+		$this->setCall($token, 'getPassword', 'password');
+		$this->setException($token);
+
+		$result = $this->manager->getPassword($token, 'tokenId', 'password');
+
+		$this->assertSame('password', $result);
+	}
+
+	/**
+	 * @dataProvider tokenData
+	 */
+	public function testSetPassword(IToken $token) {
+		$this->setNoCall($token);
+		$this->setCall($token, 'setPassword');
+		$this->setException($token);
+
+		$this->manager->setPassword($token, 'tokenId', 'password');
+	}
+
+	public function testInvalidateTokens() {
+		$this->defaultTokenProvider->expects($this->once())
+			->method('invalidateToken')
+			->with('token');
+
+		$this->publicKeyTokenProvider->expects($this->once())
+			->method('invalidateToken')
+			->with('token');
+
+		$this->manager->invalidateToken('token');
+	}
+
+	public function testInvalidateTokenById() {
+		$this->defaultTokenProvider->expects($this->once())
+			->method('invalidateTokenById')
+			->with('uid', 42);
+
+		$this->publicKeyTokenProvider->expects($this->once())
+			->method('invalidateTokenById')
+			->with('uid', 42);
+
+		$this->manager->invalidateTokenById('uid', 42);
+	}
+
+	public function testInvalidateOldTokens() {
+		$this->defaultTokenProvider->expects($this->once())
+			->method('invalidateOldTokens');
+
+		$this->publicKeyTokenProvider->expects($this->once())
+			->method('invalidateOldTokens');
+
+		$this->manager->invalidateOldTokens();
+	}
+
+	public function testGetTokenByUser() {
+		$t1 = new DefaultToken();
+		$t2 = new DefaultToken();
+		$t3 = new PublicKeyToken();
+		$t4 = new PublicKeyToken();
+
+		$this->defaultTokenProvider
+			->method('getTokenByUser')
+			->willReturn([$t1, $t2]);
+
+		$this->publicKeyTokenProvider
+			->method('getTokenByUser')
+			->willReturn([$t3, $t4]);
+
+		$result = $this->manager->getTokenByUser('uid');
+
+		$this->assertEquals([$t1, $t2, $t3, $t4], $result);
+	}
+
+	public function testRenewSessionTokenPublicKey() {
+		$this->defaultTokenProvider->expects($this->never())
+			->method($this->anything());
+
+		$this->publicKeyTokenProvider->expects($this->once())
+			->method('renewSessionToken')
+			->with('oldId', 'newId');
+
+		$this->manager->renewSessionToken('oldId', 'newId');
+	}
+
+	public function testRenewSessionTokenDefault() {
+		$this->publicKeyTokenProvider->expects($this->once())
+			->method('renewSessionToken')
+			->with('oldId', 'newId')
+			->willThrowException(new InvalidTokenException());
+
+		$this->defaultTokenProvider->expects($this->once())
+			->method('renewSessionToken')
+			->with('oldId', 'newId');
+
+		$this->manager->renewSessionToken('oldId', 'newId');
+	}
+
+	public function testRenewSessionInvalid() {
+		$this->publicKeyTokenProvider->expects($this->once())
+			->method('renewSessionToken')
+			->with('oldId', 'newId')
+			->willThrowException(new InvalidTokenException());
+
+		$this->defaultTokenProvider->expects($this->once())
+			->method('renewSessionToken')
+			->with('oldId', 'newId')
+			->willThrowException(new InvalidTokenException());
+
+		$this->expectException(InvalidTokenException::class);
+		$this->manager->renewSessionToken('oldId', 'newId');
+	}
+
+	public function testGetTokenByIdPublicKey() {
+		$token = $this->createMock(IToken::class);
+
+		$this->publicKeyTokenProvider->expects($this->once())
+			->method('getTokenById')
+			->with(42)
+			->willReturn($token);
+
+		$this->defaultTokenProvider->expects($this->never())
+			->method($this->anything());
+
+
+		$this->assertSame($token, $this->manager->getTokenById(42));
+	}
+
+	public function testGetTokenByIdDefault() {
+		$token = $this->createMock(IToken::class);
+
+		$this->publicKeyTokenProvider->expects($this->once())
+			->method('getTokenById')
+			->with(42)
+			->willThrowException(new InvalidTokenException());
+
+		$this->defaultTokenProvider->expects($this->once())
+			->method('getTokenById')
+			->with(42)
+			->willReturn($token);
+
+		$this->assertSame($token, $this->manager->getTokenById(42));
+	}
+
+	public function testGetTokenByIdInvalid() {
+		$this->publicKeyTokenProvider->expects($this->once())
+			->method('getTokenById')
+			->with(42)
+			->willThrowException(new InvalidTokenException());
+
+		$this->defaultTokenProvider->expects($this->once())
+			->method('getTokenById')
+			->with(42)
+			->willThrowException(new InvalidTokenException());
+
+		$this->expectException(InvalidTokenException::class);
+		$this->manager->getTokenById(42);
+	}
+
+	public function testGetTokenPublicKey() {
+		$token = new PublicKeyToken();
+
+		$this->defaultTokenProvider->expects($this->never())
+			->method($this->anything());
+
+		$this->publicKeyTokenProvider
+			->method('getToken')
+			->with('tokenId')
+			->willReturn($token);
+
+		$this->assertSame($token, $this->manager->getToken('tokenId'));
+	}
+
+	public function testGetTokenInvalid() {
+		$this->defaultTokenProvider
+			->method('getToken')
+			->with('tokenId')
+			->willThrowException(new InvalidTokenException());
+
+		$this->publicKeyTokenProvider
+			->method('getToken')
+			->with('tokenId')
+			->willThrowException(new InvalidTokenException());
+
+		$this->expectException(InvalidTokenException::class);
+		$this->manager->getToken('tokenId');
+	}
+
+	public function testGetTokenConvertPassword() {
+		$oldToken = new DefaultToken();
+		$newToken = new PublicKeyToken();
+
+		$this->publicKeyTokenProvider
+			->method('getToken')
+			->with('tokenId')
+			->willThrowException(new InvalidTokenException());
+
+		$this->defaultTokenProvider
+			->method('getToken')
+			->willReturn($oldToken);
+
+		$this->defaultTokenProvider
+			->method('getPassword')
+			->with($oldToken, 'tokenId')
+			->willReturn('password');
+
+		$this->publicKeyTokenProvider
+			->method('convertToken')
+			->with($oldToken, 'tokenId', 'password')
+			->willReturn($newToken);
+
+		$this->assertSame($newToken, $this->manager->getToken('tokenId'));
+	}
+
+	public function testGetTokenConvertNoPassword() {
+		$oldToken = new DefaultToken();
+		$newToken = new PublicKeyToken();
+
+		$this->publicKeyTokenProvider
+			->method('getToken')
+			->with('tokenId')
+			->willThrowException(new InvalidTokenException());
+
+		$this->defaultTokenProvider
+			->method('getToken')
+			->willReturn($oldToken);
+
+		$this->defaultTokenProvider
+			->method('getPassword')
+			->with($oldToken, 'tokenId')
+			->willThrowException(new PasswordlessTokenException());
+
+		$this->publicKeyTokenProvider
+			->method('convertToken')
+			->with($oldToken, 'tokenId', null)
+			->willReturn($newToken);
+
+		$this->assertSame($newToken, $this->manager->getToken('tokenId'));
+	}
+
+	public function testRotateInvalid() {
+		$this->expectException(InvalidTokenException::class);
+		$this->manager->rotate($this->createMock(IToken::class), 'oldId', 'newId');
+	}
+
+	public function testRotatePublicKey() {
+		$token = new PublicKeyToken();
+
+		$this->publicKeyTokenProvider
+			->method('rotate')
+			->with($token, 'oldId', 'newId')
+			->willReturn($token);
+
+		$this->assertSame($token, $this->manager->rotate($token, 'oldId', 'newId'));
+	}
+
+	public function testRotateConvertPassword() {
+		$oldToken = new DefaultToken();
+		$newToken = new PublicKeyToken();
+
+		$this->defaultTokenProvider
+			->method('getPassword')
+			->with($oldToken, 'oldId')
+			->willReturn('password');
+
+		$this->publicKeyTokenProvider
+			->method('convertToken')
+			->with($oldToken, 'newId', 'password')
+			->willReturn($newToken);
+
+		$this->assertSame($newToken, $this->manager->rotate($oldToken, 'oldId', 'newId'));
+	}
+
+	public function testRotateConvertNoPassword() {
+		$oldToken = new DefaultToken();
+		$newToken = new PublicKeyToken();
+
+		$this->defaultTokenProvider
+			->method('getPassword')
+			->with($oldToken, 'oldId')
+			->willThrowException(new PasswordlessTokenException());
+
+		$this->publicKeyTokenProvider
+			->method('convertToken')
+			->with($oldToken, 'newId', null)
+			->willReturn($newToken);
+
+		$this->assertSame($newToken, $this->manager->rotate($oldToken, 'oldId', 'newId'));
+	}
+}
diff --git a/tests/lib/Authentication/Token/PublicKeyTokenMapperTest.php b/tests/lib/Authentication/Token/PublicKeyTokenMapperTest.php
index 7c4dbabad6c..ce4de92e193 100644
--- a/tests/lib/Authentication/Token/PublicKeyTokenMapperTest.php
+++ b/tests/lib/Authentication/Token/PublicKeyTokenMapperTest.php
@@ -204,23 +204,11 @@ class PublicKeyTokenMapperTest extends TestCase {
 	}
 
 	public function testGetTokenByUser() {
-		/** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */
-		$user = $this->createMock(IUser::class);
-		$user->expects($this->once())
-			->method('getUID')
-			->will($this->returnValue('user1'));
-
-		$this->assertCount(2, $this->mapper->getTokenByUser($user));
+		$this->assertCount(2, $this->mapper->getTokenByUser('user1'));
 	}
 
 	public function testGetTokenByUserNotFound() {
-		/** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */
-		$user = $this->createMock(IUser::class);
-		$user->expects($this->once())
-			->method('getUID')
-			->will($this->returnValue('user1000'));
-
-		$this->assertCount(0, $this->mapper->getTokenByUser($user));
+		$this->assertCount(0, $this->mapper->getTokenByUser('user1000'));
 	}
 
 	public function testDeleteById() {
@@ -232,11 +220,8 @@ class PublicKeyTokenMapperTest extends TestCase {
 			->where($qb->expr()->eq('token', $qb->createNamedParameter('9c5a2e661482b65597408a6bb6c4a3d1af36337381872ac56e445a06cdb7fea2b1039db707545c11027a4966919918b19d875a8b774840b18c6cbb7ae56fe206')));
 		$result = $qb->execute();
 		$id = $result->fetch()['id'];
-		$user->expects($this->once())
-			->method('getUID')
-			->will($this->returnValue('user1'));
 
-		$this->mapper->deleteById($user, (int)$id);
+		$this->mapper->deleteById('user1', (int)$id);
 		$this->assertEquals(2, $this->getNumberOfTokens());
 	}
 
@@ -244,11 +229,8 @@ class PublicKeyTokenMapperTest extends TestCase {
 		/** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */
 		$user = $this->createMock(IUser::class);
 		$id = 33;
-		$user->expects($this->once())
-			->method('getUID')
-			->will($this->returnValue('user10000'));
 
-		$this->mapper->deleteById($user, $id);
+		$this->mapper->deleteById('user1000', $id);
 		$this->assertEquals(3, $this->getNumberOfTokens());
 	}
 
diff --git a/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php b/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php
index d5cfe5d1ee6..cd3bcb81ba6 100644
--- a/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php
+++ b/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php
@@ -25,6 +25,7 @@ namespace Test\Authentication\Token;
 
 use OC\Authentication\Exceptions\InvalidTokenException;
 use OC\Authentication\Exceptions\PasswordlessTokenException;
+use OC\Authentication\Token\DefaultToken;
 use OC\Authentication\Token\PublicKeyToken;
 use OC\Authentication\Token\PublicKeyTokenMapper;
 use OC\Authentication\Token\PublicKeyTokenProvider;
@@ -357,7 +358,7 @@ class PublicKeyTokenProviderTest extends TestCase {
 				$this->callback(function (string $token) {
 					return hash('sha512', 'unhashedToken'.'1f4h9s') === $token;
 				})
-			)->willThrowException(new InvalidTokenException());
+			)->willThrowException(new DoesNotExistException('nope'));
 
 		$this->tokenProvider->getToken('unhashedToken');
 	}
@@ -471,4 +472,35 @@ class PublicKeyTokenProviderTest extends TestCase {
 		$this->assertNotSame($newPrivate, $oldPrivate);
 		$this->assertNull($new->getPassword());
 	}
+
+	public function testConvertToken() {
+		$defaultToken = new DefaultToken();
+		$defaultToken->setId(42);
+		$defaultToken->setPassword('oldPass');
+		$defaultToken->setExpires(1337);
+		$defaultToken->setToken('oldToken');
+		$defaultToken->setUid('uid');
+		$defaultToken->setLoginName('loginName');
+		$defaultToken->setLastActivity(999);
+		$defaultToken->setName('name');
+		$defaultToken->setRemember(IToken::REMEMBER);
+		$defaultToken->setType(IToken::PERMANENT_TOKEN);
+
+		$this->mapper->expects($this->once())
+			->method('update')
+			->willReturnArgument(0);
+
+		$newToken = $this->tokenProvider->convertToken($defaultToken, 'newToken', 'newPassword');
+
+		$this->assertSame(42, $newToken->getId());
+		$this->assertSame('newPassword', $this->tokenProvider->getPassword($newToken, 'newToken'));
+		$this->assertSame(1337, $newToken->getExpires());
+		$this->assertSame('uid', $newToken->getUID());
+		$this->assertSame('loginName', $newToken->getLoginName());
+		$this->assertSame(1313131, $newToken->getLastActivity());
+		$this->assertSame(1313131, $newToken->getLastCheck());
+		$this->assertSame('name', $newToken->getName());
+		$this->assertSame(IToken::REMEMBER, $newToken->getRemember());
+		$this->assertSame(IToken::PERMANENT_TOKEN, $newToken->getType());
+	}
 }
-- 
GitLab