Let apps register contact menu provider via info.xml

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
Christoph Wurst 2017-04-03 18:04:14 +02:00
parent 5762cd9436
commit 36cee1f386
6 changed files with 125 additions and 33 deletions

View File

@ -28,23 +28,24 @@ use OC\Contacts\ContactsMenu\Manager;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest; use OCP\IRequest;
use OCP\IUserSession;
class ContactsMenuController extends Controller { class ContactsMenuController extends Controller {
/** @var Manager */ /** @var Manager */
private $manager; private $manager;
/** @var string */ /** @var IUserSession */
private $userId; private $userSession;
/** /**
* @param IRequest $request * @param IRequest $request
* @param string $UserId * @param IUserSession $userSession
* @param Manager $manager * @param Manager $manager
*/ */
public function __construct(IRequest $request, $UserId, Manager $manager) { public function __construct(IRequest $request, IUserSession $userSession, Manager $manager) {
parent::__construct('core', $request); parent::__construct('core', $request);
$this->userId = $UserId; $this->userSession = $userSession;
$this->manager = $manager; $this->manager = $manager;
} }
@ -55,7 +56,7 @@ class ContactsMenuController extends Controller {
* @return JSONResponse * @return JSONResponse
*/ */
public function index($filter = null) { public function index($filter = null) {
return $this->manager->getEntries($this->userId, $filter); return $this->manager->getEntries($this->userSession->getUser(), $filter);
} }
} }

View File

@ -24,38 +24,49 @@
namespace OC\Contacts\ContactsMenu; namespace OC\Contacts\ContactsMenu;
use Exception;
use OC\App\AppManager;
use OC\Contacts\ContactsMenu\Providers\EMailProvider; use OC\Contacts\ContactsMenu\Providers\EMailProvider;
use OCP\AppFramework\QueryException; use OCP\AppFramework\QueryException;
use OCP\Contacts\ContactsMenu\IProvider; use OCP\Contacts\ContactsMenu\IProvider;
use OCP\ILogger; use OCP\ILogger;
use OCP\IServerContainer; use OCP\IServerContainer;
use OCP\IUser;
class ActionProviderStore { class ActionProviderStore {
/** @var IServerContainer */ /** @var IServerContainer */
private $serverContainer; private $serverContainer;
/** @var AppManager */
private $appManager;
/** @var ILogger */ /** @var ILogger */
private $logger; private $logger;
/** /**
* @param IServerContainer $serverContainer * @param IServerContainer $serverContainer
* @param AppManager $appManager
* @param ILogger $logger
*/ */
public function __construct(IServerContainer $serverContainer, ILogger $logger) { public function __construct(IServerContainer $serverContainer, AppManager $appManager, ILogger $logger) {
$this->serverContainer = $serverContainer; $this->serverContainer = $serverContainer;
$this->appManager = $appManager;
$this->logger = $logger; $this->logger = $logger;
} }
/** /**
* @param IUser $user
* @return IProvider[] * @return IProvider[]
* @throws Exception * @throws Exception
*/ */
public function getProviders() { public function getProviders(IUser $user) {
// TODO: include apps $appClasses = $this->getAppProviderClasses($user);
$providerClasses = $this->getServerProviderClasses(); $providerClasses = $this->getServerProviderClasses();
$allClasses = array_merge($providerClasses, $appClasses);
$providers = []; $providers = [];
foreach ($providerClasses as $class) { foreach ($allClasses as $class) {
try { try {
$providers[] = $this->serverContainer->query($class); $providers[] = $this->serverContainer->query($class);
} catch (QueryException $ex) { } catch (QueryException $ex) {
@ -63,7 +74,7 @@ class ActionProviderStore {
'message' => "Could not load contacts menu action provider $class", 'message' => "Could not load contacts menu action provider $class",
'app' => 'core', 'app' => 'core',
]); ]);
throw new \Exception("Could not load contacts menu action provider"); throw new Exception("Could not load contacts menu action provider");
} }
} }
@ -79,4 +90,25 @@ class ActionProviderStore {
]; ];
} }
/**
* @param IUser $user
* @return string[]
*/
private function getAppProviderClasses(IUser $user) {
return array_reduce($this->appManager->getEnabledAppsForUser($user), function($all, $appId) {
$info = $this->appManager->getAppInfo($appId);
if (!isset($info['contactsmenu']) || !isset($info['contactsmenu'])) {
// Nothing to add
return $all;
}
$providers = array_reduce($info['contactsmenu'], function($all, $provider) {
return array_merge($all, [$provider]);
}, []);
return array_merge($all, $providers);
}, []);
}
} }

View File

@ -27,6 +27,7 @@ namespace OC\Contacts\ContactsMenu;
use OCP\App\IAppManager; use OCP\App\IAppManager;
use OCP\Contacts\ContactsMenu\IEntry; use OCP\Contacts\ContactsMenu\IEntry;
use OCP\IURLGenerator; use OCP\IURLGenerator;
use OCP\IUser;
class Manager { class Manager {
@ -39,9 +40,6 @@ class Manager {
/** @var IAppManager */ /** @var IAppManager */
private $appManager; private $appManager;
/** @var IURLGenerator */
private $urlGenerator;
/** /**
* @param ContactsStore $store * @param ContactsStore $store
* @param ActionProviderStore $actionProviderStore * @param ActionProviderStore $actionProviderStore
@ -54,18 +52,18 @@ class Manager {
} }
/** /**
* @param string $userId * @param string $user
* @param string $filter * @param string $filter
* @return array * @return array
*/ */
public function getEntries($userId, $filter) { public function getEntries(IUser $user, $filter) {
$entries = $this->store->getContacts($filter); $entries = $this->store->getContacts($filter);
$sortedEntries = $this->sortEntries($entries); $sortedEntries = $this->sortEntries($entries);
$topEntries = array_slice($sortedEntries, 0, 25); $topEntries = array_slice($sortedEntries, 0, 25);
$this->processEntries($topEntries); $this->processEntries($topEntries, $user);
$contactsEnabled = $this->appManager->isEnabledForUser('contacts', $userId); $contactsEnabled = $this->appManager->isEnabledForUser('contacts', $user);
return [ return [
'contacts' => $topEntries, 'contacts' => $topEntries,
'contactsAppEnabled' => $contactsEnabled, 'contactsAppEnabled' => $contactsEnabled,
@ -85,9 +83,10 @@ class Manager {
/** /**
* @param IEntry[] $entries * @param IEntry[] $entries
* @param IUser $user
*/ */
private function processEntries(array $entries) { private function processEntries(array $entries, IUser $user) {
$providers = $this->actionProviderStore->getProviders(); $providers = $this->actionProviderStore->getProviders($user);
foreach ($entries as $entry) { foreach ($entries as $entry) {
foreach ($providers as $provider) { foreach ($providers as $provider) {
$provider->process($entry); $provider->process($entry);

View File

@ -28,6 +28,8 @@ use OC\Contacts\ContactsMenu\Manager;
use OC\Core\Controller\ContactsMenuController; use OC\Core\Controller\ContactsMenuController;
use OCP\Contacts\ContactsMenu\IEntry; use OCP\Contacts\ContactsMenu\IEntry;
use OCP\IRequest; use OCP\IRequest;
use OCP\IUser;
use OCP\IUserSession;
use PHPUnit_Framework_MockObject_MockObject; use PHPUnit_Framework_MockObject_MockObject;
use Test\TestCase; use Test\TestCase;
@ -36,8 +38,8 @@ class ContactsMenuControllerTest extends TestCase {
/** @var IRequest|PHPUnit_Framework_MockObject_MockObject */ /** @var IRequest|PHPUnit_Framework_MockObject_MockObject */
private $request; private $request;
/** @var string */ /** @var IUserSession|PHPUnit_Framework_MockObject_MockObject */
private $userId; private $userSession;
/** @var Manager|PHPUnit_Framework_MockObject_MockObject */ /** @var Manager|PHPUnit_Framework_MockObject_MockObject */
private $contactsManager; private $contactsManager;
@ -49,20 +51,24 @@ class ContactsMenuControllerTest extends TestCase {
parent::setUp(); parent::setUp();
$this->request = $this->createMock(IRequest::class); $this->request = $this->createMock(IRequest::class);
$this->userId = 'user4563'; $this->userSession = $this->createMock(IUserSession::class);
$this->contactsManager = $this->createMock(Manager::class); $this->contactsManager = $this->createMock(Manager::class);
$this->controller = new ContactsMenuController($this->request, $this->userId, $this->contactsManager); $this->controller = new ContactsMenuController($this->request, $this->userSession, $this->contactsManager);
} }
public function testIndex() { public function testIndex() {
$user = $this->createMock(IUser::class);
$entries = [ $entries = [
$this->createMock(IEntry::class), $this->createMock(IEntry::class),
$this->createMock(IEntry::class), $this->createMock(IEntry::class),
]; ];
$this->userSession->expects($this->once())
->method('getUser')
->willReturn($user);
$this->contactsManager->expects($this->once()) $this->contactsManager->expects($this->once())
->method('getEntries') ->method('getEntries')
->with($this->equalTo($this->userId), $this->equalTo(null)) ->with($this->equalTo($user), $this->equalTo(null))
->willReturn($entries); ->willReturn($entries);
$response = $this->controller->index(); $response = $this->controller->index();

View File

@ -25,11 +25,15 @@
namespace Tests\Contacts\ContactsMenu; namespace Tests\Contacts\ContactsMenu;
use Exception; use Exception;
use OC\App\AppManager;
use OC\Contacts\ContactsMenu\ActionProviderStore; use OC\Contacts\ContactsMenu\ActionProviderStore;
use OC\Contacts\ContactsMenu\Providers\EMailProvider; use OC\Contacts\ContactsMenu\Providers\EMailProvider;
use OCP\App\IAppManager;
use OCP\AppFramework\QueryException; use OCP\AppFramework\QueryException;
use OCP\Contacts\ContactsMenu\IProvider;
use OCP\ILogger; use OCP\ILogger;
use OCP\IServerContainer; use OCP\IServerContainer;
use OCP\IUser;
use PHPUnit_Framework_MockObject_MockObject; use PHPUnit_Framework_MockObject_MockObject;
use Test\TestCase; use Test\TestCase;
@ -38,6 +42,9 @@ class ActionProviderStoreTest extends TestCase {
/** @var IServerContainer|PHPUnit_Framework_MockObject_MockObject */ /** @var IServerContainer|PHPUnit_Framework_MockObject_MockObject */
private $serverContainer; private $serverContainer;
/** @var IAppManager|PHPUnit_Framework_MockObject_MockObject */
private $appManager;
/** @var ILogger|PHPUnit_Framework_MockObject_MockObject */ /** @var ILogger|PHPUnit_Framework_MockObject_MockObject */
private $logger; private $logger;
@ -48,19 +55,61 @@ class ActionProviderStoreTest extends TestCase {
parent::setUp(); parent::setUp();
$this->serverContainer = $this->createMock(IServerContainer::class); $this->serverContainer = $this->createMock(IServerContainer::class);
$this->appManager = $this->createMock(AppManager::class);
$this->logger = $this->createMock(ILogger::class); $this->logger = $this->createMock(ILogger::class);
$this->actionProviderStore = new ActionProviderStore($this->serverContainer, $this->logger);
$this->actionProviderStore = new ActionProviderStore($this->serverContainer, $this->appManager, $this->logger);
} }
public function testGetProviders() { public function testGetProviders() {
$emailProvider = $this->createMock(EMailProvider::class); $user = $this->createMock(IUser::class);
$provider1 = $this->createMock(EMailProvider::class);
$provider2 = $this->createMock(IProvider::class);
$this->appManager->expects($this->once())
->method('getEnabledAppsForUser')
->with($user)
->willReturn(['contacts']);
$this->appManager->expects($this->once())
->method('getAppInfo')
->with('contacts')
->willReturn([
'contactsmenu' => [
'OCA\Contacts\Provider1',
],
]);
$this->serverContainer->expects($this->exactly(2)) $this->serverContainer->expects($this->exactly(2))
->method('query') ->method('query')
->will($this->returnValueMap([ ->will($this->returnValueMap([
[EMailProvider::class, $emailProvider], [EMailProvider::class, $provider1],
['OCA\Contacts\Provider1', $provider2]
])); ]));
$providers = $this->actionProviderStore->getProviders(); $providers = $this->actionProviderStore->getProviders($user);
$this->assertCount(2, $providers);
$this->assertInstanceOf(EMailProvider::class, $providers[0]);
}
public function testGetProvidersOfAppWithIncompleInfo() {
$user = $this->createMock(IUser::class);
$provider1 = $this->createMock(EMailProvider::class);
$this->appManager->expects($this->once())
->method('getEnabledAppsForUser')
->with($user)
->willReturn(['contacts']);
$this->appManager->expects($this->once())
->method('getAppInfo')
->with('contacts')
->willReturn([/* Empty info.xml */]);
$this->serverContainer->expects($this->once())
->method('query')
->will($this->returnValueMap([
[EMailProvider::class, $provider1],
]));
$providers = $this->actionProviderStore->getProviders($user);
$this->assertCount(1, $providers); $this->assertCount(1, $providers);
$this->assertInstanceOf(EMailProvider::class, $providers[0]); $this->assertInstanceOf(EMailProvider::class, $providers[0]);
@ -70,13 +119,16 @@ class ActionProviderStoreTest extends TestCase {
* @expectedException Exception * @expectedException Exception
*/ */
public function testGetProvidersWithQueryException() { public function testGetProvidersWithQueryException() {
$emailProvider = $this->createMock(EMailProvider::class); $user = $this->createMock(IUser::class);
$detailsProvider = $this->createMock(DetailsProvider::class); $this->appManager->expects($this->once())
->method('getEnabledAppsForUser')
->with($user)
->willReturn([]);
$this->serverContainer->expects($this->once()) $this->serverContainer->expects($this->once())
->method('query') ->method('query')
->willThrowException(new QueryException()); ->willThrowException(new QueryException());
$providers = $this->actionProviderStore->getProviders(); $this->actionProviderStore->getProviders($user);
} }
} }

View File

@ -30,6 +30,7 @@ use OC\Contacts\ContactsMenu\Manager;
use OCP\App\IAppManager; use OCP\App\IAppManager;
use OCP\Contacts\ContactsMenu\IEntry; use OCP\Contacts\ContactsMenu\IEntry;
use OCP\Contacts\ContactsMenu\IProvider; use OCP\Contacts\ContactsMenu\IProvider;
use OCP\IUser;
use PHPUnit_Framework_MockObject_MockObject; use PHPUnit_Framework_MockObject_MockObject;
use Test\TestCase; use Test\TestCase;
@ -71,7 +72,7 @@ class ManagerTest extends TestCase {
public function testGetFilteredEntries() { public function testGetFilteredEntries() {
$filter = 'con'; $filter = 'con';
$user = 'user849'; $user = $this->createMock(IUser::class);
$entries = $this->generateTestEntries(); $entries = $this->generateTestEntries();
$provider = $this->createMock(IProvider::class); $provider = $this->createMock(IProvider::class);
$this->contactsStore->expects($this->once()) $this->contactsStore->expects($this->once())
@ -80,6 +81,7 @@ class ManagerTest extends TestCase {
->willReturn($entries); ->willReturn($entries);
$this->actionProviderStore->expects($this->once()) $this->actionProviderStore->expects($this->once())
->method('getProviders') ->method('getProviders')
->with($user)
->willReturn([$provider]); ->willReturn([$provider]);
$provider->expects($this->exactly(25)) $provider->expects($this->exactly(25))
->method('process'); ->method('process');