diff --git a/apps/settings/lib/Controller/AppSettingsController.php b/apps/settings/lib/Controller/AppSettingsController.php index b0a1b5a49dbf7..5f687cd00ca56 100644 --- a/apps/settings/lib/Controller/AppSettingsController.php +++ b/apps/settings/lib/Controller/AppSettingsController.php @@ -69,6 +69,7 @@ public function __construct( private CategoryFetcher $categoryFetcher, private AppFetcher $appFetcher, private IFactory $l10nFactory, + private IGroupManager $groupManager, private BundleFetcher $bundleFetcher, private Installer $installer, private IURLGenerator $urlGenerator, @@ -94,6 +95,13 @@ public function viewApps(): TemplateResponse { $this->initialState->provideInitialState('appstoreBundles', $this->getBundles()); $this->initialState->provideInitialState('appstoreUpdateCount', count($this->getAppsWithUpdates())); + $groups = array_map(static fn (IGroup $group): array => [ + 'id' => $group->getGID(), + 'name' => $group->getDisplayName(), + ], $this->groupManager->search('', 5)); + + $this->initialState->provideInitialState('usersSettings', [ 'systemGroups' => $groups]); + if ($this->appManager->isEnabledForAnyone('app_api')) { try { Server::get(ExAppsPageService::class)->provideAppApiState($this->initialState); diff --git a/apps/settings/tests/Controller/AppSettingsControllerTest.php b/apps/settings/tests/Controller/AppSettingsControllerTest.php index 63094264ebfd8..357e05733d7de 100644 --- a/apps/settings/tests/Controller/AppSettingsControllerTest.php +++ b/apps/settings/tests/Controller/AppSettingsControllerTest.php @@ -21,6 +21,8 @@ use OCP\Files\AppData\IAppDataFactory; use OCP\Http\Client\IClientService; use OCP\IConfig; +use OCP\IGroup; +use OCP\IGroupManager; use OCP\IL10N; use OCP\INavigationManager; use OCP\IRequest; @@ -45,6 +47,7 @@ class AppSettingsControllerTest extends TestCase { private CategoryFetcher&MockObject $categoryFetcher; private AppFetcher&MockObject $appFetcher; private IFactory&MockObject $l10nFactory; + private IGroupManager&MockObject $groupManager; private BundleFetcher&MockObject $bundleFetcher; private Installer&MockObject $installer; private IURLGenerator&MockObject $urlGenerator; @@ -70,6 +73,7 @@ protected function setUp(): void { $this->categoryFetcher = $this->createMock(CategoryFetcher::class); $this->appFetcher = $this->createMock(AppFetcher::class); $this->l10nFactory = $this->createMock(IFactory::class); + $this->groupManager = $this->createMock(IGroupManager::class); $this->bundleFetcher = $this->createMock(BundleFetcher::class); $this->installer = $this->createMock(Installer::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); @@ -89,6 +93,7 @@ protected function setUp(): void { $this->categoryFetcher, $this->appFetcher, $this->l10nFactory, + $this->groupManager, $this->bundleFetcher, $this->installer, $this->urlGenerator, @@ -168,9 +173,16 @@ public function testViewApps(): void { ->expects($this->once()) ->method('setActiveEntry') ->with('core_apps'); + $this->groupManager->expects($this->once()) + ->method('search') + ->with($this->equalTo(''), $this->equalTo(5)) + ->willReturn([ + $this->createMock(IGroup::class), + $this->createMock(IGroup::class), + ]); $this->initialState - ->expects($this->exactly(3)) + ->expects($this->exactly(4)) ->method('provideInitialState'); $policy = new ContentSecurityPolicy(); @@ -201,9 +213,16 @@ public function testViewAppsAppstoreNotEnabled(): void { ->expects($this->once()) ->method('setActiveEntry') ->with('core_apps'); + $this->groupManager->expects($this->once()) + ->method('search') + ->with($this->equalTo(''), $this->equalTo(5)) + ->willReturn([ + $this->createMock(IGroup::class), + $this->createMock(IGroup::class), + ]); $this->initialState - ->expects($this->exactly(3)) + ->expects($this->exactly(4)) ->method('provideInitialState'); $policy = new ContentSecurityPolicy(); diff --git a/cypress/e2e/settings/apps.cy.ts b/cypress/e2e/settings/apps.cy.ts index 604017015b66b..bfff8befaac94 100644 --- a/cypress/e2e/settings/apps.cy.ts +++ b/cypress/e2e/settings/apps.cy.ts @@ -142,6 +142,34 @@ describe('Settings: App management', { testIsolation: true }, () => { cy.get('#app-sidebar-vue').contains(/Version \d+\.\d+\.\d+/).should('be.visible') }) + it('Limit app usage to group', () => { + // When I open the "Active apps" section + cy.get('#app-category-enabled a') + .should('contain', 'Active apps') + .click({ force: true }) + // Then I see that the current section is "Active apps" + cy.url().should('match', /settings\/apps\/enabled$/) + cy.get('#app-category-enabled').find('.active').should('exist') + // Then I select the app + cy.get('#apps-list') + .should('exist') + .contains('tr', 'Dashboard', { timeout: 10000 }) + .click() + // Then I enable "limit app to group" + cy.get('[for="groups_enable_dashboard"]').click() + // Then I select a group + cy.get('#limitToGroups').click() + cy.get('ul[role="listbox"]') + .find('span') + .contains('admin') + .click() + cy.get('span.name-parts__first') + .contains('admin') + .should('be.visible') + // Then I disable the group limitation + cy.get('button[title="Deselect admin"]').click() + }) + /* * TODO: Improve testing with app store as external API * The following scenarios require the files_antivirus and calendar app