diff options
author | provokateurin <kate@provokateurin.de> | 2024-09-04 17:48:30 +0200 |
---|---|---|
committer | provokateurin <kate@provokateurin.de> | 2024-09-09 11:04:36 +0200 |
commit | d5e98cd190249906aa7547528b3e7123fb6cb94b (patch) | |
tree | d44477ca2d45a090e8452d21e0cb7d2fcf7b97eb | |
parent | 0a3093d05da92036684afb5814a4925b443468f7 (diff) | |
download | nextcloud-server-d5e98cd190249906aa7547528b3e7123fb6cb94b.tar.gz nextcloud-server-d5e98cd190249906aa7547528b3e7123fb6cb94b.zip |
fix(NavigationManager): Skip invalid default navigation entries
Signed-off-by: provokateurin <kate@provokateurin.de>
-rw-r--r-- | apps/theming/lib/Settings/Admin.php | 4 | ||||
-rw-r--r-- | apps/theming/tests/Settings/AdminTest.php | 6 | ||||
-rw-r--r-- | lib/private/NavigationManager.php | 37 | ||||
-rw-r--r-- | tests/lib/NavigationManagerTest.php | 57 |
4 files changed, 90 insertions, 14 deletions
diff --git a/apps/theming/lib/Settings/Admin.php b/apps/theming/lib/Settings/Admin.php index 640a2a8346d..24ac0729de5 100644 --- a/apps/theming/lib/Settings/Admin.php +++ b/apps/theming/lib/Settings/Admin.php @@ -14,6 +14,7 @@ use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; use OCP\IConfig; use OCP\IL10N; +use OCP\INavigationManager; use OCP\IURLGenerator; use OCP\Settings\IDelegatedSettings; use OCP\Util; @@ -28,6 +29,7 @@ class Admin implements IDelegatedSettings { private IInitialState $initialState, private IURLGenerator $urlGenerator, private ImageManager $imageManager, + private INavigationManager $navigationManager, ) { } @@ -70,7 +72,7 @@ class Admin implements IDelegatedSettings { 'docUrlIcons' => $this->urlGenerator->linkToDocs('admin-theming-icons'), 'canThemeIcons' => $this->imageManager->shouldReplaceIcons(), 'userThemingDisabled' => $this->themingDefaults->isUserThemingDisabled(), - 'defaultApps' => array_filter(explode(',', $this->config->getSystemValueString('defaultapp', ''))), + 'defaultApps' => $this->navigationManager->getDefaultEntryIds(), ]); Util::addScript($this->appName, 'admin-theming'); diff --git a/apps/theming/tests/Settings/AdminTest.php b/apps/theming/tests/Settings/AdminTest.php index 489d807673f..d74668f5e6f 100644 --- a/apps/theming/tests/Settings/AdminTest.php +++ b/apps/theming/tests/Settings/AdminTest.php @@ -13,6 +13,7 @@ use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; use OCP\IConfig; use OCP\IL10N; +use OCP\INavigationManager; use OCP\IURLGenerator; use Test\TestCase; @@ -24,6 +25,7 @@ class AdminTest extends TestCase { private IURLGenerator $urlGenerator; private ImageManager $imageManager; private IL10N $l10n; + private INavigationManager $navigationManager; protected function setUp(): void { parent::setUp(); @@ -33,6 +35,7 @@ class AdminTest extends TestCase { $this->initialState = $this->createMock(IInitialState::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); $this->imageManager = $this->createMock(ImageManager::class); + $this->navigationManager = $this->createMock(INavigationManager::class); $this->admin = new Admin( Application::APP_ID, @@ -41,7 +44,8 @@ class AdminTest extends TestCase { $this->themingDefaults, $this->initialState, $this->urlGenerator, - $this->imageManager + $this->imageManager, + $this->navigationManager, ); } diff --git a/lib/private/NavigationManager.php b/lib/private/NavigationManager.php index e1fbb02fda4..169c7aaf350 100644 --- a/lib/private/NavigationManager.php +++ b/lib/private/NavigationManager.php @@ -44,8 +44,6 @@ class NavigationManager implements INavigationManager { private $groupManager; /** @var IConfig */ private $config; - /** The default entry for the current user (cached for the `add` function) */ - private ?string $defaultEntry; /** User defined app order (cached for the `add` function) */ private array $customAppOrder; private LoggerInterface $logger; @@ -66,8 +64,6 @@ class NavigationManager implements INavigationManager { $this->groupManager = $groupManager; $this->config = $config; $this->logger = $logger; - - $this->defaultEntry = null; } /** @@ -100,13 +96,22 @@ class NavigationManager implements INavigationManager { $entry['app'] = $id; } - // This is the default app that will always be shown first - $entry['default'] = ($entry['id'] ?? false) === $this->defaultEntry; // Set order from user defined app order $entry['order'] = (int)($this->customAppOrder[$id]['order'] ?? $entry['order'] ?? 100); } $this->entries[$id] = $entry; + + // Needs to be done after adding the new entry to account for the default entries containing this new entry. + $this->updateDefaultEntries(); + } + + private function updateDefaultEntries() { + foreach ($this->entries as $id => $entry) { + if ($entry['type'] === 'link') { + $this->entries[$id]['default'] = $id === $this->getDefaultEntryIdForUser($this->userSession->getUser(), false); + } + } } /** @@ -221,8 +226,6 @@ class NavigationManager implements INavigationManager { ]); } - $this->defaultEntry = $this->getDefaultEntryIdForUser($this->userSession->getUser(), false); - if ($this->userSession->isLoggedIn()) { // Profile $this->add([ @@ -422,8 +425,8 @@ class NavigationManager implements INavigationManager { public function getDefaultEntryIdForUser(?IUser $user = null, bool $withFallbacks = true): string { $this->init(); - $defaultEntryIds = explode(',', $this->config->getSystemValueString('defaultapp', '')); - $defaultEntryIds = array_filter($defaultEntryIds); + // Disable fallbacks here, as we need to override them with the user defaults if none are configured. + $defaultEntryIds = $this->getDefaultEntryIds(false); $user ??= $this->userSession->getUser(); @@ -461,8 +464,18 @@ class NavigationManager implements INavigationManager { return $withFallbacks ? 'files' : ''; } - public function getDefaultEntryIds(): array { - return explode(',', $this->config->getSystemValueString('defaultapp', 'dashboard,files')); + public function getDefaultEntryIds(bool $withFallbacks = true): array { + $this->init(); + $storedIds = explode(',', $this->config->getSystemValueString('defaultapp', $withFallbacks ? 'dashboard,files' : '')); + $ids = []; + $entryIds = array_keys($this->entries); + foreach ($storedIds as $id) { + if (in_array($id, $entryIds, true)) { + $ids[] = $id; + break; + } + } + return array_filter($ids); } public function setDefaultEntryIds(array $ids): void { diff --git a/tests/lib/NavigationManagerTest.php b/tests/lib/NavigationManagerTest.php index 416b4730147..27f14e97bb0 100644 --- a/tests/lib/NavigationManagerTest.php +++ b/tests/lib/NavigationManagerTest.php @@ -724,4 +724,61 @@ class NavigationManagerTest extends TestCase { $this->assertEquals($expectedApp, $this->navigationManager->getDefaultEntryIdForUser(null, $withFallbacks)); } + + public function testDefaultEntryUpdated() { + $this->appManager->method('getInstalledApps')->willReturn([]); + + $user = $this->createMock(IUser::class); + $user->method('getUID')->willReturn('user1'); + + $this->userSession + ->method('getUser') + ->willReturn($user); + + $this->config + ->method('getSystemValueString') + ->with('defaultapp', $this->anything()) + ->willReturn('app4,app3,app2,app1'); + + $this->config + ->method('getUserValue') + ->willReturnMap([ + ['user1', 'core', 'defaultapp', '', ''], + ['user1', 'core', 'apporder', '[]', ''], + ]); + + $this->navigationManager->add([ + 'id' => 'app1', + ]); + + $this->assertEquals('app1', $this->navigationManager->getDefaultEntryIdForUser(null, false)); + $this->assertEquals(true, $this->navigationManager->get('app1')['default']); + + $this->navigationManager->add([ + 'id' => 'app3', + ]); + + $this->assertEquals('app3', $this->navigationManager->getDefaultEntryIdForUser(null, false)); + $this->assertEquals(false, $this->navigationManager->get('app1')['default']); + $this->assertEquals(true, $this->navigationManager->get('app3')['default']); + + $this->navigationManager->add([ + 'id' => 'app2', + ]); + + $this->assertEquals('app3', $this->navigationManager->getDefaultEntryIdForUser(null, false)); + $this->assertEquals(false, $this->navigationManager->get('app1')['default']); + $this->assertEquals(false, $this->navigationManager->get('app2')['default']); + $this->assertEquals(true, $this->navigationManager->get('app3')['default']); + + $this->navigationManager->add([ + 'id' => 'app4', + ]); + + $this->assertEquals('app4', $this->navigationManager->getDefaultEntryIdForUser(null, false)); + $this->assertEquals(false, $this->navigationManager->get('app1')['default']); + $this->assertEquals(false, $this->navigationManager->get('app2')['default']); + $this->assertEquals(false, $this->navigationManager->get('app3')['default']); + $this->assertEquals(true, $this->navigationManager->get('app4')['default']); + } } |