api()->loginWebAndGetToken( DatabaseSeeder::ADMIN_USERNAME, DatabaseSeeder::PASSWORD )['token']; $res = $this->api()->withToken($token, 'GET', 'translations', null, ['languages' => '1']); $this->assertApiOk($res); $this->assertIsArray($res['data']['languages']); } public function testListQuestionsForQuestionnaire(): void { $token = $this->api()->loginWebAndGetToken( DatabaseSeeder::ADMIN_USERNAME, DatabaseSeeder::PASSWORD )['token']; $f = $this->fixture(); $res = $this->api()->withToken($token, 'GET', 'questions', null, [ 'questionnaireID' => $f->questionnaireId, ]); $this->assertApiOk($res); $ids = array_column($res['data']['questions'], 'questionID'); $this->assertContains($f->questionId, $ids); } public function testListAnswerOptions(): void { $token = $this->api()->loginWebAndGetToken( DatabaseSeeder::ADMIN_USERNAME, DatabaseSeeder::PASSWORD )['token']; $res = $this->api()->withToken($token, 'GET', 'answer_options', null, [ 'questionID' => $this->fixture()->questionId, ]); $this->assertApiOk($res); $this->assertNotEmpty($res['data']['answerOptions']); } public function testListCoachesForSupervisor(): void { $token = $this->api()->loginWebAndGetToken( DatabaseSeeder::SUPERVISOR_USERNAME, DatabaseSeeder::PASSWORD )['token']; $res = $this->api()->withToken($token, 'GET', 'coaches'); $this->assertApiOk($res); $coachIds = array_column($res['data']['coaches'], 'coachID'); $this->assertContains($this->fixture()->coachId, $coachIds); } public function testTranslationsAllDashboard(): void { $token = $this->api()->loginWebAndGetToken( DatabaseSeeder::ADMIN_USERNAME, DatabaseSeeder::PASSWORD )['token']; $res = $this->api()->withToken($token, 'GET', 'translations', null, ['all' => '1']); $this->assertApiOk($res); $this->assertArrayHasKey('questionnaires', $res['data']); $this->assertArrayHasKey('entries', $res['data']); } public function testTranslationsForQuestionnaire(): void { $token = $this->api()->loginWebAndGetToken( DatabaseSeeder::ADMIN_USERNAME, DatabaseSeeder::PASSWORD )['token']; $res = $this->api()->withToken($token, 'GET', 'translations', null, [ 'questionnaireID' => $this->fixture()->questionnaireId, ]); $this->assertApiOk($res); $this->assertArrayHasKey('entries', $res['data']); } public function testAppTranslationsRequiresAuth(): void { $res = $this->api()->request('GET', 'app_questionnaires', null, [], ['translations' => '1']); $this->assertApiError($res, 'UNAUTHORIZED', 401); } public function testAppLoginTranslationsPublicNoAuth(): void { $res = $this->api()->request('GET', 'app_questionnaires', null, [], ['loginTranslations' => '1']); $this->assertApiOk($res); $this->assertArrayHasKey('translations', $res['data']); $map = $res['data']['translations']; $this->assertIsArray($map); // Must include auth / help_auth keys and must not dump unrelated catalog keys. $foundAuth = false; $foundHelp = false; $forbidden = false; foreach ($map as $lang => $strings) { $this->assertIsArray($strings); foreach ($strings as $key => $text) { $this->assertTrue( qdb_is_public_login_translation_key((string)$key), "Unexpected public key: {$key}" ); if (str_starts_with((string)$key, 'auth_')) { $foundAuth = true; } if (str_starts_with((string)$key, 'help_auth_')) { $foundHelp = true; } if ((string)$key === 'client_code' || (string)$key === 'client_picker_title') { $forbidden = true; } } } $this->assertTrue($foundAuth); $this->assertTrue($foundHelp); $this->assertFalse($forbidden); } public function testAppTranslationsWithToken(): void { $login = $this->api()->loginMobileAndGetToken( DatabaseSeeder::COACH_USERNAME, DatabaseSeeder::PASSWORD ); $res = $this->api()->withMobileToken($login['token'], 'GET', 'app_questionnaires', null, [ 'translations' => '1', ]); $this->assertApiOk($res); $this->assertArrayHasKey('translations', $res['data']); } }