112 lines
4.2 KiB
PHP
112 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Integration;
|
|
|
|
use Tests\Support\DatabaseSeeder;
|
|
use Tests\Support\QdbTestCase;
|
|
|
|
final class QuestionnaireEditingTest extends QdbTestCase
|
|
{
|
|
public function testAdminCreatesQuestion(): void
|
|
{
|
|
$token = $this->api()->loginWebAndGetToken(
|
|
DatabaseSeeder::ADMIN_USERNAME,
|
|
DatabaseSeeder::PASSWORD
|
|
)['token'];
|
|
$f = $this->fixture();
|
|
$res = $this->api()->withToken($token, 'POST', 'questions', [
|
|
'questionnaireID' => $f->questionnaireId,
|
|
'questionKey' => 'extra_q',
|
|
'defaultText' => 'Extra question text',
|
|
'type' => 'free_text',
|
|
'isRequired' => 0,
|
|
'configJson' => '{}',
|
|
]);
|
|
$this->assertApiOk($res);
|
|
$this->assertSame('extra_q', $res['data']['question']['questionKey'] ?? '');
|
|
}
|
|
|
|
public function testAdminCreatesAnswerOption(): void
|
|
{
|
|
$token = $this->api()->loginWebAndGetToken(
|
|
DatabaseSeeder::ADMIN_USERNAME,
|
|
DatabaseSeeder::PASSWORD
|
|
)['token'];
|
|
$f = $this->fixture();
|
|
$res = $this->api()->withToken($token, 'POST', 'answer_options', [
|
|
'questionID' => $f->questionId,
|
|
'optionKey' => 'no_option',
|
|
'defaultText' => 'No',
|
|
'points' => 0,
|
|
]);
|
|
$this->assertApiOk($res);
|
|
$this->assertSame('no_option', $res['data']['answerOption']['optionKey'] ?? '');
|
|
}
|
|
|
|
public function testAnswerOptionsRequireQuestionId(): void
|
|
{
|
|
$token = $this->api()->loginWebAndGetToken(
|
|
DatabaseSeeder::ADMIN_USERNAME,
|
|
DatabaseSeeder::PASSWORD
|
|
)['token'];
|
|
$res = $this->api()->withToken($token, 'GET', 'answer_options');
|
|
$this->assertApiError($res, 'MISSING_PARAM', 400);
|
|
}
|
|
|
|
public function testSavingNoteBeforeBumpsStructureRevisionAndExportsKey(): void
|
|
{
|
|
$adminToken = $this->api()->loginWebAndGetToken(
|
|
DatabaseSeeder::ADMIN_USERNAME,
|
|
DatabaseSeeder::PASSWORD
|
|
)['token'];
|
|
$coachLogin = $this->api()->loginMobileAndGetToken(
|
|
DatabaseSeeder::COACH_USERNAME,
|
|
DatabaseSeeder::PASSWORD
|
|
);
|
|
$f = $this->fixture();
|
|
|
|
$before = $this->api()->withMobileToken($coachLogin['token'], 'GET', 'app_questionnaires', null, [
|
|
'id' => $f->questionnaireId,
|
|
]);
|
|
$this->assertApiOk($before);
|
|
$revBefore = (int)($before['data']['structureRevision'] ?? 1);
|
|
|
|
$put = $this->api()->withToken($adminToken, 'PUT', 'questions', [
|
|
'questionID' => $f->questionId,
|
|
'questionKey' => 'consent_q',
|
|
'defaultText' => 'Consent?',
|
|
'type' => 'single_choice_question',
|
|
'isRequired' => 1,
|
|
'configJson' => json_encode(['questionKey' => 'consent_q'], JSON_UNESCAPED_UNICODE),
|
|
'noteBefore' => 'Bitte dem Klienten deutlich machen: Ohne Einwilligung keine Teilnahme.',
|
|
'noteAfter' => '',
|
|
]);
|
|
$this->assertApiOk($put);
|
|
$revAfter = (int)($put['data']['structureRevision'] ?? 0);
|
|
$this->assertGreaterThan($revBefore, $revAfter, 'note-only edit must bump structureRevision for app sync');
|
|
|
|
$detail = $this->api()->withMobileToken($coachLogin['token'], 'GET', 'app_questionnaires', null, [
|
|
'id' => $f->questionnaireId,
|
|
]);
|
|
$this->assertApiOk($detail);
|
|
$questions = $detail['data']['questions'] ?? [];
|
|
$this->assertIsArray($questions);
|
|
$matched = null;
|
|
foreach ($questions as $q) {
|
|
if (($q['question'] ?? '') === 'consent_q' || ($q['id'] ?? '') === 'q1') {
|
|
$matched = $q;
|
|
break;
|
|
}
|
|
}
|
|
$this->assertNotNull($matched, 'expected consent question in app export');
|
|
$this->assertSame('consent_q_note_before', $matched['noteBeforeKey'] ?? null);
|
|
$de = $detail['data']['translations']['de'] ?? [];
|
|
$this->assertSame(
|
|
'Bitte dem Klienten deutlich machen: Ohne Einwilligung keine Teilnahme.',
|
|
$de['consent_q_note_before'] ?? null
|
|
);
|
|
}
|
|
}
|