From b9db77bab75ff4af299612fa03cda1204c4e8bf3 Mon Sep 17 00:00:00 2001 From: Tatjana Kaschperko Lindt Date: Fri, 19 Jul 2024 15:33:25 +0200 Subject: [PATCH] feat: provide getLanguageMap to PageController Inspired from from apps/settings/lib/Settings/Personal/PersonalInfo.php Combines commonLanguages and otherLanguages to allLanguages for frontend. Co-Authored-By: Thomas Lehmann Signed-off-by: Tatjana Kaschperko Lindt --- lib/Controller/PageController.php | 69 +++++++++++++++ tests/Controller/PageControllerTest.php | 107 +++++++++++++++++++++++- 2 files changed, 173 insertions(+), 3 deletions(-) diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 443e38c..c97523f 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -34,14 +34,27 @@ use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; use OCP\Authentication\Exceptions\InvalidTokenException; +use OCP\IConfig; use OCP\ISession; +use OCP\IUser; +use OCP\IUserManager; use OCP\IUserSession; +use OCP\L10N\IFactory; use OCP\Session\Exceptions\SessionNotAvailableException; /** * @psalm-suppress UnusedClass */ class PageController extends Controller { + /** @var IConfig */ + private $config; + + /** @var IUserManager */ + private $userManager; + + /** @var IFactory */ + private $l10nFactory; + /** @var IProvider */ private $tokenProvider; @@ -58,12 +71,18 @@ class PageController extends Controller { private $uid; public function __construct( + IConfig $config, + IUserManager $userManager, + IFactory $l10nFactory, IAuthTokenProvider $tokenProvider, ISession $session, IInitialState $initialState, IUserSession $userSession, ?string $UserId ) { + $this->config = $config; + $this->userManager = $userManager; + $this->l10nFactory = $l10nFactory; $this->tokenProvider = $tokenProvider; $this->session = $session; $this->initialState = $initialState; @@ -86,6 +105,15 @@ public function index(): TemplateResponse { $this->userSession->getImpersonatingUserID() === null ); + $user = $this->userManager->get($this->uid); + + $this->initialState->provideInitialState( + 'personalInfoParameters', + [ + 'languageMap' => $this->getLanguageMap($user), + ] + ); + return new TemplateResponse( Application::APP_ID, 'index', @@ -118,4 +146,45 @@ private function getAppTokens(): array { return $data; }, $tokens); } + + /** + * returns the user's active language, common languages, and other languages in an + * associative array + */ + private function getLanguageMap(IUser $user): array { + $forceLanguage = $this->config->getSystemValue('force_language', false); + if ($forceLanguage !== false) { + return []; + } + + $uid = $user->getUID(); + + $userConfLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage()); + $languages = $this->l10nFactory->getLanguages(); + + $combinedLanguages = array_merge( + $languages['commonLanguages'], + $languages['otherLanguages'] + ); + + $userLangIndex = array_search($userConfLang, array_column($combinedLanguages, 'code')); + $userLang = null; + + if ($userLangIndex !== false) { + $userLang = $combinedLanguages[$userLangIndex]; + } + + // if user language is not available but set somehow: show the actual code as name + if (!is_array($userLang)) { + $userLang = [ + 'code' => $userConfLang, + 'name' => $userConfLang, + ]; + } + + return [ + 'activeLanguage' => $userLang, + 'allLanguages' => $combinedLanguages + ]; + } } diff --git a/tests/Controller/PageControllerTest.php b/tests/Controller/PageControllerTest.php index ae4d312..172ac14 100644 --- a/tests/Controller/PageControllerTest.php +++ b/tests/Controller/PageControllerTest.php @@ -28,6 +28,7 @@ use OCP\AppFramework\Services\IInitialState; use OCP\IConfig; use OCP\ISession; +use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; use OCP\L10N\IFactory; @@ -119,6 +120,50 @@ protected function setUp(): void { $this->tokenProvider->expects($this->once()) ->method('getToken') ->willReturn($mockSessionAppToken); + + // Mocks for getLanguageMap() + + $this->mockedForcedLanguage = false; + + $this->mockUserUid = 'some-mock-uid'; + $this->mockConfiguredUserLanguage = 'xx-XX'; + $this->mockAvailableLanguages = [ + 'commonLanguages' => [ + ['code' => 'de-DE', 'name' => 'Deutsch'], + ], + 'otherLanguages' => [ + ['code' => 'ru-RU', 'name' => 'Русский'], + ] + ]; + + $mockUser = $this->createMock(IUser::class); + + $mockUser->expects($this->atMost(1)) + ->method('getUID') + ->willReturn($this->mockUserUid); + + $this->userManager->expects($this->atMost(1)) + ->method('get') + ->with($this->equalTo($this->uid)) + ->willReturn($mockUser); + + $this->config->expects($this->atMost(1)) + ->method('getSystemValue') + ->with('force_language', false) + ->willReturnCallback(fn($_propertyName, $_defaultValue) => $this->mockedForcedLanguage); + + $this->l10nFactory->expects($this->atMost(1)) + ->method('findLanguage') + ->willReturnCallback(fn() => $this->mockConfiguredUserLanguage); + + $this->config->expects($this->atMost(1)) + ->method('getUserValue') + ->with($this->mockUserUid, 'core', 'lang', $this->anything()) + ->willReturnCallback(fn($userId, $_appName, $_properyName, $_defaultValue) => $this->mockConfiguredUserLanguage); + + $this->l10nFactory->expects($this->atMost(1)) + ->method('getLanguages') + ->willReturn($this->mockAvailableLanguages); } /** @@ -167,7 +212,7 @@ public function testIndexProvidesInitialStateWithAppTokens() { ], ]; - $this->initialState->expects($this->exactly(2)) + $this->initialState->expects($this->exactly(3)) ->method('provideInitialState') ->willReturnCallback(function($stateName, $stateValue) use ($expectedAppTokensRegisteredAsInitialState) { if ($stateName == "app_tokens") { @@ -188,7 +233,7 @@ public function testIndexProvidesInitialStateWithCanCreateAppTokensFalse() { ->method('getImpersonatingUserID') ->willReturn("some-user-id-is-not-null"); - $this->initialState->expects($this->exactly(2)) + $this->initialState->expects($this->exactly(3)) ->method('provideInitialState') ->willReturnCallback(function ($stateName, $stateValue) { if ($stateName == "can_create_app_token") { @@ -207,7 +252,7 @@ public function testIndexProvidesInitialStateWithCanCreateAppTokensTrue() { ->method('getImpersonatingUserID') ->willReturn(null); - $this->initialState->expects($this->exactly(2)) + $this->initialState->expects($this->exactly(3)) ->method('provideInitialState') ->willReturnCallback(function($stateName, $stateValue) { if ($stateName == "can_create_app_token") { @@ -217,4 +262,60 @@ public function testIndexProvidesInitialStateWithCanCreateAppTokensTrue() { $this->controller->index(); } + + private function configureInitialStateLanguageMock($expectedActiveLanguage) { + $mockAvailableLanguages = $this->mockAvailableLanguages; + + $this->initialState->expects($this->exactly(3)) + ->method('provideInitialState') + ->willReturnCallback(function($stateName, $stateValue) use ($expectedActiveLanguage, $mockAvailableLanguages) { + if ($stateName == "personalInfoParameters") { + $this->assertEquals([ + 'languageMap' => [ + 'activeLanguage' => $expectedActiveLanguage, + 'allLanguages' => array_merge( + $mockAvailableLanguages['commonLanguages'], + $mockAvailableLanguages['otherLanguages'], + ) + ] + ], $stateValue); + } + }); + } + + /** + * @throws Exception + */ + public function testIndexProvidesInitialStateWithLanguagesLanguageForced() { + $this->mockedForcedLanguage = true; + + $this->initialState->expects($this->exactly(3)) + ->method('provideInitialState') + ->willReturnCallback(function($stateName, $stateValue) { + if ($stateName == "personalInfoParameters") { + $this->assertEquals([ + 'languageMap' => [] + ], $stateValue); + } + }); + + $this->controller->index(); + } + + /** + * @throws Exception + */ + public function testIndexProvidesInitialStateWithLanguagesNoLanguageForcedAndConfiguredLanguageNotFound() { + $this->configureInitialStateLanguageMock(['code' => $this->mockConfiguredUserLanguage, 'name' => $this->mockConfiguredUserLanguage]); + $this->controller->index(); + } + + /** + * @throws Exception + */ + public function testIndexProvidesInitialStateWithLanguagesNoLanguageForcedAndConfiguredLanguageFound() { + $this->mockConfiguredUserLanguage = 'de-DE'; + $this->configureInitialStateLanguageMock(['code' => $this->mockConfiguredUserLanguage, 'name' => 'Deutsch']); + $this->controller->index(); + } }