aboutsummaryrefslogtreecommitdiffstats
path: root/tests/lib/Accounts/AccountManagerTest.php
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib/Accounts/AccountManagerTest.php')
-rw-r--r--tests/lib/Accounts/AccountManagerTest.php517
1 files changed, 380 insertions, 137 deletions
diff --git a/tests/lib/Accounts/AccountManagerTest.php b/tests/lib/Accounts/AccountManagerTest.php
index 9d54ef36c80..c625644bd96 100644
--- a/tests/lib/Accounts/AccountManagerTest.php
+++ b/tests/lib/Accounts/AccountManagerTest.php
@@ -1,45 +1,37 @@
<?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/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Test\Accounts;
use OC\Accounts\Account;
use OC\Accounts\AccountManager;
+use OC\PhoneNumberUtil;
use OCA\Settings\BackgroundJobs\VerifyUserData;
use OCP\Accounts\IAccountManager;
+use OCP\Accounts\UserUpdatedEvent;
use OCP\BackgroundJob\IJobList;
use OCP\Defaults;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Http\Client\IClient;
+use OCP\Http\Client\IClientService;
+use OCP\Http\Client\IResponse;
use OCP\IConfig;
use OCP\IDBConnection;
+use OCP\IPhoneNumberUtil;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\L10N\IFactory;
use OCP\Mail\IMailer;
use OCP\Security\ICrypto;
use OCP\Security\VerificationToken\IVerificationToken;
+use OCP\Server;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-use Symfony\Component\EventDispatcher\GenericEvent;
use Test\TestCase;
/**
@@ -49,44 +41,31 @@ use Test\TestCase;
* @package Test\Accounts
*/
class AccountManagerTest extends TestCase {
- /** @var IVerificationToken|MockObject */
- protected $verificationToken;
- /** @var IMailer|MockObject */
- protected $mailer;
- /** @var ICrypto|MockObject */
- protected $crypto;
- /** @var IURLGenerator|MockObject */
- protected $urlGenerator;
- /** @var Defaults|MockObject */
- protected $defaults;
- /** @var IFactory|MockObject */
- protected $l10nFactory;
-
- /** @var \OCP\IDBConnection */
- private $connection;
-
- /** @var IConfig|MockObject */
- private $config;
-
- /** @var EventDispatcherInterface|MockObject */
- private $eventDispatcher;
-
- /** @var IJobList|MockObject */
- private $jobList;
- /** @var string accounts table name */
- private $table = 'accounts';
+ /** accounts table name */
+ private string $table = 'accounts';
+ private AccountManager $accountManager;
+ private IDBConnection $connection;
+ private IPhoneNumberUtil $phoneNumberUtil;
- /** @var LoggerInterface|MockObject */
- private $logger;
-
- /** @var AccountManager */
- private $accountManager;
+ protected IVerificationToken&MockObject $verificationToken;
+ protected IMailer&MockObject $mailer;
+ protected ICrypto&MockObject $crypto;
+ protected IURLGenerator&MockObject $urlGenerator;
+ protected Defaults&MockObject $defaults;
+ protected IFactory&MockObject $l10nFactory;
+ protected IConfig&MockObject $config;
+ protected IEventDispatcher&MockObject $eventDispatcher;
+ protected IJobList&MockObject $jobList;
+ private LoggerInterface&MockObject $logger;
+ private IClientService&MockObject $clientService;
protected function setUp(): void {
parent::setUp();
- $this->eventDispatcher = $this->createMock(EventDispatcherInterface::class);
- $this->connection = \OC::$server->get(IDBConnection::class);
+ $this->connection = Server::get(IDBConnection::class);
+ $this->phoneNumberUtil = new PhoneNumberUtil();
+
+ $this->eventDispatcher = $this->createMock(IEventDispatcher::class);
$this->config = $this->createMock(IConfig::class);
$this->jobList = $this->createMock(IJobList::class);
$this->logger = $this->createMock(LoggerInterface::class);
@@ -96,6 +75,7 @@ class AccountManagerTest extends TestCase {
$this->l10nFactory = $this->createMock(IFactory::class);
$this->urlGenerator = $this->createMock(IURLGenerator::class);
$this->crypto = $this->createMock(ICrypto::class);
+ $this->clientService = $this->createMock(IClientService::class);
$this->accountManager = new AccountManager(
$this->connection,
@@ -108,17 +88,19 @@ class AccountManagerTest extends TestCase {
$this->defaults,
$this->l10nFactory,
$this->urlGenerator,
- $this->crypto
+ $this->crypto,
+ $this->phoneNumberUtil,
+ $this->clientService,
);
}
protected function tearDown(): void {
parent::tearDown();
$query = $this->connection->getQueryBuilder();
- $query->delete($this->table)->execute();
+ $query->delete($this->table)->executeStatement();
}
- protected function makeUser(string $uid, string $name, string $email = null): IUser {
+ protected function makeUser(string $uid, string $name, ?string $email = null): IUser {
$user = $this->createMock(IUser::class);
$user->expects($this->any())
->method('getUid')
@@ -156,6 +138,11 @@ class AccountManagerTest extends TestCase {
'scope' => IAccountManager::SCOPE_PUBLISHED
],
[
+ 'name' => IAccountManager::PROPERTY_FEDIVERSE,
+ 'value' => '@someMastodon@mastodon.social',
+ 'scope' => IAccountManager::SCOPE_PUBLISHED
+ ],
+ [
'name' => IAccountManager::PROPERTY_PHONE,
'value' => '+491601231212',
'scope' => IAccountManager::SCOPE_FEDERATED
@@ -211,6 +198,11 @@ class AccountManagerTest extends TestCase {
'scope' => IAccountManager::SCOPE_FEDERATED
],
[
+ 'name' => IAccountManager::PROPERTY_FEDIVERSE,
+ 'value' => '@a_alice@cool.social',
+ 'scope' => IAccountManager::SCOPE_FEDERATED
+ ],
+ [
'name' => IAccountManager::PROPERTY_PHONE,
'value' => '+491602312121',
'scope' => IAccountManager::SCOPE_LOCAL
@@ -266,6 +258,11 @@ class AccountManagerTest extends TestCase {
'scope' => IAccountManager::SCOPE_LOCAL
],
[
+ 'name' => IAccountManager::PROPERTY_FEDIVERSE,
+ 'value' => '',
+ 'scope' => IAccountManager::SCOPE_LOCAL
+ ],
+ [
'name' => IAccountManager::PROPERTY_PHONE,
'value' => '+491603121212',
'scope' => IAccountManager::SCOPE_PUBLISHED
@@ -321,6 +318,11 @@ class AccountManagerTest extends TestCase {
scope' => IAccountManager::SCOPE_LOCAL
],
[
+ 'name' => IAccountManager::PROPERTY_FEDIVERSE,
+ 'value' => '', '
+ scope' => IAccountManager::SCOPE_LOCAL
+ ],
+ [
'name' => IAccountManager::PROPERTY_PHONE,
'value' => '+71601212123',
'scope' => IAccountManager::SCOPE_LOCAL
@@ -386,6 +388,11 @@ class AccountManagerTest extends TestCase {
'scope' => IAccountManager::SCOPE_LOCAL
],
[
+ 'name' => IAccountManager::PROPERTY_FEDIVERSE,
+ 'value' => '',
+ 'scope' => IAccountManager::SCOPE_LOCAL
+ ],
+ [
'name' => IAccountManager::PROPERTY_PHONE,
'value' => '+71602121231',
'scope' => IAccountManager::SCOPE_FEDERATED
@@ -423,18 +430,18 @@ class AccountManagerTest extends TestCase {
],
],
];
+ $this->config->expects($this->exactly(count($users)))->method('getSystemValue')->with('account_manager.default_property_scope', [])->willReturn([]);
foreach ($users as $userInfo) {
- $this->invokePrivate($this->accountManager, 'updateUser', [$userInfo['user'], $userInfo['data'], false]);
+ $this->invokePrivate($this->accountManager, 'updateUser', [$userInfo['user'], $userInfo['data'], null, false]);
}
}
/**
* get a instance of the accountManager
*
- * @param array $mockedMethods list of methods which should be mocked
* @return MockObject | AccountManager
*/
- public function getInstance($mockedMethods = null) {
+ public function getInstance(?array $mockedMethods = null) {
return $this->getMockBuilder(AccountManager::class)
->setConstructorArgs([
$this->connection,
@@ -447,28 +454,20 @@ class AccountManagerTest extends TestCase {
$this->defaults,
$this->l10nFactory,
$this->urlGenerator,
- $this->crypto
+ $this->crypto,
+ $this->phoneNumberUtil,
+ $this->clientService,
])
- ->setMethods($mockedMethods)
+ ->onlyMethods($mockedMethods)
->getMock();
}
- /**
- * @dataProvider dataTrueFalse
- *
- * @param array $newData
- * @param array $oldData
- * @param bool $insertNew
- * @param bool $updateExisting
- */
- public function testUpdateUser($newData, $oldData, $insertNew, $updateExisting) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataTrueFalse')]
+ public function testUpdateUser(array $newData, array $oldData, bool $insertNew, bool $updateExisting): void {
$accountManager = $this->getInstance(['getUser', 'insertNewUser', 'updateExistingUser']);
/** @var IUser $user */
$user = $this->createMock(IUser::class);
- // FIXME: should be an integration test instead of this abomination
- $accountManager->expects($this->once())->method('getUser')->with($user)->willReturn($oldData);
-
if ($updateExisting) {
$accountManager->expects($this->once())->method('updateExistingUser')
->with($user, $newData);
@@ -483,24 +482,22 @@ class AccountManagerTest extends TestCase {
if (!$insertNew && !$updateExisting) {
$accountManager->expects($this->never())->method('updateExistingUser');
$accountManager->expects($this->never())->method('insertNewUser');
- $this->eventDispatcher->expects($this->never())->method('dispatch');
+ $this->eventDispatcher->expects($this->never())->method('dispatchTyped');
} else {
- $this->eventDispatcher->expects($this->once())->method('dispatch')
+ $this->eventDispatcher->expects($this->once())->method('dispatchTyped')
->willReturnCallback(
- function ($eventName, $event) use ($user, $newData) {
- $this->assertSame('OC\AccountManager::userUpdated', $eventName);
- $this->assertInstanceOf(GenericEvent::class, $event);
- /** @var GenericEvent $event */
- $this->assertSame($user, $event->getSubject());
- $this->assertSame($newData, $event->getArguments());
+ function ($event) use ($user, $newData): void {
+ $this->assertInstanceOf(UserUpdatedEvent::class, $event);
+ $this->assertSame($user, $event->getUser());
+ $this->assertSame($newData, $event->getData());
}
);
}
- $this->invokePrivate($accountManager, 'updateUser', [$user, $newData]);
+ $this->invokePrivate($accountManager, 'updateUser', [$user, $newData, $oldData]);
}
- public function dataTrueFalse() {
+ public static function dataTrueFalse(): array {
return [
#$newData | $oldData | $insertNew | $updateExisting
[['myProperty' => ['value' => 'newData']], ['myProperty' => ['value' => 'oldData']], false, true],
@@ -508,7 +505,7 @@ class AccountManagerTest extends TestCase {
];
}
- public function testAddMissingDefaults() {
+ public function testAddMissingDefaults(): void {
$user = $this->createMock(IUser::class);
$this->config
@@ -578,6 +575,20 @@ class AccountManagerTest extends TestCase {
],
[
+ 'name' => IAccountManager::PROPERTY_BLUESKY,
+ 'value' => '',
+ 'scope' => IAccountManager::SCOPE_LOCAL,
+ 'verified' => IAccountManager::NOT_VERIFIED,
+ ],
+
+ [
+ 'name' => IAccountManager::PROPERTY_FEDIVERSE,
+ 'value' => '',
+ 'scope' => IAccountManager::SCOPE_LOCAL,
+ 'verified' => IAccountManager::NOT_VERIFIED,
+ ],
+
+ [
'name' => IAccountManager::PROPERTY_ORGANISATION,
'value' => '',
'scope' => IAccountManager::SCOPE_LOCAL,
@@ -602,10 +613,23 @@ class AccountManagerTest extends TestCase {
],
[
+ 'name' => IAccountManager::PROPERTY_BIRTHDATE,
+ 'value' => '',
+ 'scope' => IAccountManager::SCOPE_LOCAL,
+ ],
+
+ [
'name' => IAccountManager::PROPERTY_PROFILE_ENABLED,
'value' => '1',
],
+
+ [
+ 'name' => IAccountManager::PROPERTY_PRONOUNS,
+ 'value' => '',
+ 'scope' => IAccountManager::SCOPE_FEDERATED,
+ ],
];
+ $this->config->expects($this->once())->method('getSystemValue')->with('account_manager.default_property_scope', [])->willReturn([]);
$defaultUserRecord = $this->invokePrivate($this->accountManager, 'buildDefaultUserRecord', [$user]);
$result = $this->invokePrivate($this->accountManager, 'addMissingDefaultValues', [$input, $defaultUserRecord]);
@@ -613,19 +637,7 @@ class AccountManagerTest extends TestCase {
$this->assertSame($expected, $result);
}
- 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();
- }
-
- public function testGetAccount() {
+ public function testGetAccount(): void {
$accountManager = $this->getInstance(['getUser']);
/** @var IUser $user */
$user = $this->createMock(IUser::class);
@@ -638,6 +650,12 @@ class AccountManagerTest extends TestCase {
'name' => IAccountManager::PROPERTY_TWITTER,
],
[
+ 'value' => '@mastohandle@mastodon.social',
+ 'scope' => IAccountManager::SCOPE_LOCAL,
+ 'verified' => IAccountManager::NOT_VERIFIED,
+ 'name' => IAccountManager::PROPERTY_FEDIVERSE,
+ ],
+ [
'value' => 'test@example.com',
'scope' => IAccountManager::SCOPE_PUBLISHED,
'verified' => IAccountManager::VERIFICATION_IN_PROGRESS,
@@ -652,6 +670,7 @@ class AccountManagerTest extends TestCase {
];
$expected = new Account($user);
$expected->setProperty(IAccountManager::PROPERTY_TWITTER, '@twitterhandle', IAccountManager::SCOPE_LOCAL, IAccountManager::NOT_VERIFIED);
+ $expected->setProperty(IAccountManager::PROPERTY_FEDIVERSE, '@mastohandle@mastodon.social', IAccountManager::SCOPE_LOCAL, IAccountManager::NOT_VERIFIED);
$expected->setProperty(IAccountManager::PROPERTY_EMAIL, 'test@example.com', IAccountManager::SCOPE_PUBLISHED, IAccountManager::VERIFICATION_IN_PROGRESS);
$expected->setProperty(IAccountManager::PROPERTY_WEBSITE, 'https://example.com', IAccountManager::SCOPE_FEDERATED, IAccountManager::VERIFIED);
@@ -661,7 +680,7 @@ class AccountManagerTest extends TestCase {
$this->assertEquals($expected, $accountManager->getAccount($user));
}
- public function dataParsePhoneNumber(): array {
+ public static function dataParsePhoneNumber(): array {
return [
['0711 / 25 24 28-90', 'DE', '+4971125242890'],
['0711 / 25 24 28-90', '', null],
@@ -669,51 +688,222 @@ class AccountManagerTest extends TestCase {
];
}
- /**
- * @dataProvider dataParsePhoneNumber
- * @param string $phoneInput
- * @param string $defaultRegion
- * @param string|null $phoneNumber
- */
- public function testParsePhoneNumber(string $phoneInput, string $defaultRegion, ?string $phoneNumber): void {
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataParsePhoneNumber')]
+ public function testSanitizePhoneNumberOnUpdateAccount(string $phoneInput, string $defaultRegion, ?string $phoneNumber): void {
$this->config->method('getSystemValueString')
->willReturn($defaultRegion);
+ $user = $this->createMock(IUser::class);
+ $account = new Account($user);
+ $account->setProperty(IAccountManager::PROPERTY_PHONE, $phoneInput, IAccountManager::SCOPE_LOCAL, IAccountManager::NOT_VERIFIED);
+ $manager = $this->getInstance(['getUser', 'updateUser']);
+ $manager->method('getUser')
+ ->with($user, false)
+ ->willReturn([]);
+ $manager->expects($phoneNumber === null ? self::never() : self::once())
+ ->method('updateUser');
+
if ($phoneNumber === null) {
$this->expectException(\InvalidArgumentException::class);
- self::invokePrivate($this->accountManager, 'parsePhoneNumber', [$phoneInput]);
- } else {
- self::assertEquals($phoneNumber, self::invokePrivate($this->accountManager, 'parsePhoneNumber', [$phoneInput]));
+ }
+
+ $manager->updateAccount($account);
+
+ if ($phoneNumber !== null) {
+ self::assertEquals($phoneNumber, $account->getProperty(IAccountManager::PROPERTY_PHONE)->getValue());
}
}
- public function dataParseWebsite(): array {
+ public static function dataSanitizeOnUpdate(): array {
return [
- ['https://nextcloud.com', 'https://nextcloud.com'],
- ['http://nextcloud.com', 'http://nextcloud.com'],
- ['ftp://nextcloud.com', null],
- ['//nextcloud.com/', null],
- ['https:///?query', null],
+ [IAccountManager::PROPERTY_WEBSITE, 'https://nextcloud.com', 'https://nextcloud.com'],
+ [IAccountManager::PROPERTY_WEBSITE, 'http://nextcloud.com', 'http://nextcloud.com'],
+ [IAccountManager::PROPERTY_WEBSITE, 'ftp://nextcloud.com', null],
+ [IAccountManager::PROPERTY_WEBSITE, '//nextcloud.com/', null],
+ [IAccountManager::PROPERTY_WEBSITE, 'https:///?query', null],
+
+ [IAccountManager::PROPERTY_TWITTER, '@nextcloud', 'nextcloud'],
+ [IAccountManager::PROPERTY_TWITTER, '_nextcloud', '_nextcloud'],
+ [IAccountManager::PROPERTY_TWITTER, 'FooB4r', 'FooB4r'],
+ [IAccountManager::PROPERTY_TWITTER, 'X', null],
+ [IAccountManager::PROPERTY_TWITTER, 'next.cloud', null],
+ [IAccountManager::PROPERTY_TWITTER, 'ab/cd.zip', null],
+ [IAccountManager::PROPERTY_TWITTER, 'tooLongForTwitterAndX', null],
+
+ [IAccountManager::PROPERTY_FEDIVERSE, 'nextcloud@mastodon.social', 'nextcloud@mastodon.social'],
+ [IAccountManager::PROPERTY_FEDIVERSE, '@nextcloud@mastodon.xyz', 'nextcloud@mastodon.xyz'],
+ [IAccountManager::PROPERTY_FEDIVERSE, 'l33t.h4x0r@sub.localhost.local', 'l33t.h4x0r@sub.localhost.local'],
+ [IAccountManager::PROPERTY_FEDIVERSE, 'invalid/name@mastodon.social', null],
+ [IAccountManager::PROPERTY_FEDIVERSE, 'name@evil.host/malware.exe', null],
+ [IAccountManager::PROPERTY_FEDIVERSE, '@is-it-a-host-or-name', null],
+ [IAccountManager::PROPERTY_FEDIVERSE, 'only-a-name', null],
];
}
- /**
- * @dataProvider dataParseWebsite
- * @param string $websiteInput
- * @param string|null $websiteOutput
- */
- public function testParseWebsite(string $websiteInput, ?string $websiteOutput): void {
- if ($websiteOutput === null) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataSanitizeOnUpdate')]
+ public function testSanitizingOnUpdateAccount(string $property, string $input, ?string $output): void {
+
+ if ($property === IAccountManager::PROPERTY_FEDIVERSE) {
+ // We do not test the server response here we do this in the `testSanitizingFediverseServer`
+ $this->config
+ ->method('getSystemValueBool')
+ ->with('has_internet_connection', true)
+ ->willReturn(false);
+ }
+
+ $user = $this->createMock(IUser::class);
+
+ $account = new Account($user);
+ $account->setProperty($property, $input, IAccountManager::SCOPE_LOCAL, IAccountManager::NOT_VERIFIED);
+
+ $manager = $this->getInstance(['getUser', 'updateUser']);
+ $manager->method('getUser')
+ ->with($user, false)
+ ->willReturn([]);
+ $manager->expects($output === null ? self::never() : self::once())
+ ->method('updateUser');
+
+ if ($output === null) {
$this->expectException(\InvalidArgumentException::class);
- self::invokePrivate($this->accountManager, 'parseWebsite', [$websiteInput]);
+ $this->expectExceptionMessage($property);
+ }
+
+ $manager->updateAccount($account);
+
+ if ($output !== null) {
+ self::assertEquals($output, $account->getProperty($property)->getValue());
+ }
+ }
+
+ public static function dataSanitizeFediverseServer(): array {
+ return [
+ 'no internet' => [
+ '@foo@example.com',
+ 'foo@example.com',
+ false,
+ null,
+ ],
+ 'no internet - no at' => [
+ 'foo@example.com',
+ 'foo@example.com',
+ false,
+ null,
+ ],
+ 'valid response' => [
+ '@foo@example.com',
+ 'foo@example.com',
+ true,
+ json_encode([
+ 'subject' => 'acct:foo@example.com',
+ 'links' => [
+ [
+ 'rel' => 'self',
+ 'type' => 'application/activity+json',
+ 'href' => 'https://example.com/users/foo',
+ ],
+ ],
+ ]),
+ ],
+ 'valid response - no at' => [
+ 'foo@example.com',
+ 'foo@example.com',
+ true,
+ json_encode([
+ 'subject' => 'acct:foo@example.com',
+ 'links' => [
+ [
+ 'rel' => 'self',
+ 'type' => 'application/activity+json',
+ 'href' => 'https://example.com/users/foo',
+ ],
+ ],
+ ]),
+ ],
+ // failures
+ 'invalid response' => [
+ '@foo@example.com',
+ null,
+ true,
+ json_encode([
+ 'subject' => 'acct:foo@example.com',
+ 'links' => [],
+ ]),
+ ],
+ 'no response' => [
+ '@foo@example.com',
+ null,
+ true,
+ null,
+ ],
+ 'wrong user' => [
+ '@foo@example.com',
+ null,
+ true,
+ json_encode([
+ 'links' => [],
+ ]),
+ ],
+ ];
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataSanitizeFediverseServer')]
+ public function testSanitizingFediverseServer(string $input, ?string $output, bool $hasInternet, ?string $serverResponse): void {
+ $this->config->expects(self::once())
+ ->method('getSystemValueBool')
+ ->with('has_internet_connection', true)
+ ->willReturn($hasInternet);
+
+ if ($hasInternet) {
+ $client = $this->createMock(IClient::class);
+ if ($serverResponse !== null) {
+ $response = $this->createMock(IResponse::class);
+ $response->method('getBody')
+ ->willReturn($serverResponse);
+ $client->expects(self::once())
+ ->method('get')
+ ->with('https://example.com/.well-known/webfinger?resource=acct:foo@example.com')
+ ->willReturn($response);
+ } else {
+ $client->expects(self::once())
+ ->method('get')
+ ->with('https://example.com/.well-known/webfinger?resource=acct:foo@example.com')
+ ->willThrowException(new \Exception('404'));
+ }
+
+ $this->clientService
+ ->expects(self::once())
+ ->method('newClient')
+ ->willReturn($client);
} else {
- self::assertEquals($websiteOutput, self::invokePrivate($this->accountManager, 'parseWebsite', [$websiteInput]));
+ $this->clientService
+ ->expects(self::never())
+ ->method('newClient');
+ }
+
+ $user = $this->createMock(IUser::class);
+ $account = new Account($user);
+ $account->setProperty(IAccountManager::PROPERTY_FEDIVERSE, $input, IAccountManager::SCOPE_LOCAL, IAccountManager::NOT_VERIFIED);
+
+ $manager = $this->getInstance(['getUser', 'updateUser']);
+ $manager->method('getUser')
+ ->with($user, false)
+ ->willReturn([]);
+ $manager->expects($output === null ? self::never() : self::once())
+ ->method('updateUser');
+
+ if ($output === null) {
+ $this->expectException(\InvalidArgumentException::class);
+ $this->expectExceptionMessage(IAccountManager::PROPERTY_FEDIVERSE);
+ }
+
+ $manager->updateAccount($account);
+
+ if ($output !== null) {
+ self::assertEquals($output, $account->getProperty(IAccountManager::PROPERTY_FEDIVERSE)->getValue());
}
}
- /**
- * @dataProvider searchDataProvider
- */
+ #[\PHPUnit\Framework\Attributes\DataProvider('searchDataProvider')]
public function testSearchUsers(string $property, array $values, array $expected): void {
$this->populateOrUpdate();
@@ -726,7 +916,7 @@ class AccountManagerTest extends TestCase {
}
}
- public function searchDataProvider(): array {
+ public static function searchDataProvider(): array {
return [
[ #0 Search for an existing name
IAccountManager::PROPERTY_DISPLAYNAME,
@@ -778,21 +968,22 @@ class AccountManagerTest extends TestCase {
];
}
- public function dataCheckEmailVerification(): array {
+ public static function dataCheckEmailVerification(): array {
return [
- [$this->makeUser('steve', 'Steve Smith', 'steve@steve.steve'), null],
- [$this->makeUser('emma', 'Emma Morales', 'emma@emma.com'), 'emma@morales.com'],
- [$this->makeUser('sarah@web.org', 'Sarah Foster', 'sarah@web.org'), null],
- [$this->makeUser('cole@web.org', 'Cole Harrison', 'cole@web.org'), 'cole@example.com'],
- [$this->makeUser('8d29e358-cf69-4849-bbf9-28076c0b908b', 'Alice McPherson', 'alice@example.com'), 'alice@mcpherson.com'],
- [$this->makeUser('11da2744-3f4d-4c17-8c13-4c057a379237', 'James Loranger', 'james@example.com'), ''],
+ [['steve', 'Steve Smith', 'steve@steve.steve'], null],
+ [['emma', 'Emma Morales', 'emma@emma.com'], 'emma@morales.com'],
+ [['sarah@web.org', 'Sarah Foster', 'sarah@web.org'], null],
+ [['cole@web.org', 'Cole Harrison', 'cole@web.org'], 'cole@example.com'],
+ [['8d29e358-cf69-4849-bbf9-28076c0b908b', 'Alice McPherson', 'alice@example.com'], 'alice@mcpherson.com'],
+ [['11da2744-3f4d-4c17-8c13-4c057a379237', 'James Loranger', 'james@example.com'], ''],
];
}
- /**
- * @dataProvider dataCheckEmailVerification
- */
- public function testCheckEmailVerification(IUser $user, ?string $newEmail): void {
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataCheckEmailVerification')]
+ public function testCheckEmailVerification(array $userData, ?string $newEmail): void {
+ $user = $this->makeUser(...$userData);
+ // Once because of getAccount, once because of getUser
+ $this->config->expects($this->exactly(2))->method('getSystemValue')->with('account_manager.default_property_scope', [])->willReturn([]);
$account = $this->accountManager->getAccount($user);
$emailUpdated = false;
@@ -815,4 +1006,56 @@ class AccountManagerTest extends TestCase {
$oldData = $this->invokePrivate($this->accountManager, 'getUser', [$user, false]);
$this->invokePrivate($this->accountManager, 'checkEmailVerification', [$account, $oldData]);
}
+
+ public static function dataSetDefaultPropertyScopes(): array {
+ return [
+ [
+ [],
+ [
+ IAccountManager::PROPERTY_DISPLAYNAME => IAccountManager::SCOPE_FEDERATED,
+ IAccountManager::PROPERTY_ADDRESS => IAccountManager::SCOPE_LOCAL,
+ IAccountManager::PROPERTY_EMAIL => IAccountManager::SCOPE_FEDERATED,
+ IAccountManager::PROPERTY_ROLE => IAccountManager::SCOPE_LOCAL,
+ ]
+ ],
+ [
+ [
+ IAccountManager::PROPERTY_DISPLAYNAME => IAccountManager::SCOPE_FEDERATED,
+ IAccountManager::PROPERTY_EMAIL => IAccountManager::SCOPE_LOCAL,
+ IAccountManager::PROPERTY_ROLE => IAccountManager::SCOPE_PRIVATE,
+ ], [
+ IAccountManager::PROPERTY_DISPLAYNAME => IAccountManager::SCOPE_FEDERATED,
+ IAccountManager::PROPERTY_EMAIL => IAccountManager::SCOPE_LOCAL,
+ IAccountManager::PROPERTY_ROLE => IAccountManager::SCOPE_PRIVATE,
+ ]
+ ],
+ [
+ [
+ IAccountManager::PROPERTY_ADDRESS => 'invalid scope',
+ 'invalid property' => IAccountManager::SCOPE_LOCAL,
+ IAccountManager::PROPERTY_ROLE => IAccountManager::SCOPE_PRIVATE,
+ ],
+ [
+ IAccountManager::PROPERTY_ADDRESS => IAccountManager::SCOPE_LOCAL,
+ IAccountManager::PROPERTY_EMAIL => IAccountManager::SCOPE_FEDERATED,
+ IAccountManager::PROPERTY_ROLE => IAccountManager::SCOPE_PRIVATE,
+ ]
+ ],
+ ];
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataSetDefaultPropertyScopes')]
+ public function testSetDefaultPropertyScopes(array $propertyScopes, array $expectedResultScopes): void {
+ $user = $this->makeUser('steve', 'Steve Smith', 'steve@steve.steve');
+ $this->config->expects($this->once())->method('getSystemValue')->with('account_manager.default_property_scope', [])->willReturn($propertyScopes);
+
+ $result = $this->invokePrivate($this->accountManager, 'buildDefaultUserRecord', [$user]);
+ $resultProperties = array_column($result, 'name');
+
+ $this->assertEmpty(array_diff($resultProperties, IAccountManager::ALLOWED_PROPERTIES), 'Building default user record returned non-allowed properties');
+ foreach ($expectedResultScopes as $expectedResultScopeKey => $expectedResultScopeValue) {
+ $resultScope = $result[array_search($expectedResultScopeKey, $resultProperties)]['scope'];
+ $this->assertEquals($expectedResultScopeValue, $resultScope, "The result scope doesn't follow the value set into the config or defaults correctly.");
+ }
+ }
}