Skip to content

Commit

Permalink
feat: provide getLanguageMap to PageController
Browse files Browse the repository at this point in the history
Inspired from from apps/settings/lib/Settings/Personal/PersonalInfo.php

Combines commonLanguages and otherLanguages to allLanguages for frontend.

Co-Authored-By: Thomas Lehmann <[email protected]>
Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
  • Loading branch information
tanyaka and thlehmann-ionos committed Jul 23, 2024
1 parent cde593b commit b9db77b
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 3 deletions.
69 changes: 69 additions & 0 deletions lib/Controller/PageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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',
Expand Down Expand Up @@ -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
];
}
}
107 changes: 104 additions & 3 deletions tests/Controller/PageControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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") {
Expand All @@ -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") {
Expand All @@ -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") {
Expand All @@ -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();
}
}

0 comments on commit b9db77b

Please sign in to comment.