diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 41304ba6681cb419bf6803577655af6454a3d724..4c4b1b512a54339296ef77933f4f0fc76dd76311 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,9 +7,10 @@ include: - '/includes/include.drupalci.workflows.yml' variables: - _CSPELL_IGNORE_PATHS: './config/*, ./css/*, ./icons/*, ./images/*, ./README.md' + _CSPELL_IGNORE_PATHS: './config/*, ./css/*, ./icons/*, ./images/*, ./tests/*, ./README.md' _CSPELL_WORDS: 'langname, grumphp, perc, addtoany' OPT_IN_TEST_NEXT_MAJOR: 0 + _PHPUNIT_CONCURRENT: '1' composer: variables: diff --git a/config/install/filter.format.full_html.yml b/config/install/filter.format.full_html.yml new file mode 100644 index 0000000000000000000000000000000000000000..07e5c67f00a58f79dff8e884899a78cd929e5ca8 --- /dev/null +++ b/config/install/filter.format.full_html.yml @@ -0,0 +1,39 @@ +langcode: en +status: true +dependencies: + module: + - editor +name: 'Full HTML' +format: full_html +weight: 2 +filters: + editor_file_reference: + id: editor_file_reference + provider: editor + status: true + weight: 11 + settings: { } + filter_align: + id: filter_align + provider: filter + status: true + weight: 8 + settings: { } + filter_caption: + id: filter_caption + provider: filter + status: true + weight: 9 + settings: { } + filter_htmlcorrector: + id: filter_htmlcorrector + provider: filter + status: true + weight: 10 + settings: { } + filter_image_lazy_load: + id: filter_image_lazy_load + provider: filter + status: true + weight: 15 + settings: { } diff --git a/config/schema/quiz_maker.schema.yml b/config/schema/quiz_maker.schema.yml index 9b75373640af461534e3a3ae9415048f854c7b87..d3ed7560334a21fd1c754a4f50458f9a8bb51c1d 100644 --- a/config/schema/quiz_maker.schema.yml +++ b/config/schema/quiz_maker.schema.yml @@ -1,4 +1,4 @@ -field.formatter.settings.question_response: +field.formatter.settings.question_response_formatter: type: mapping label: Question Response formatter formatter settings mapping: @@ -27,3 +27,78 @@ quiz_maker.quiz_result_type.*: workflow: type: string label: 'Workflow' + +quiz_maker.question_answer_type.*: + type: config_entity + label: 'Question Answer Type' + mapping: + id: + type: string + label: 'Machine Name' + description: 'The machine-readable ID for the question answer type.' + label: + type: string + label: 'Human-readable Name' + description: 'The human-readable name for the question answer type.' + plugin: + type: string + label: 'Plugin ID' + description: 'The plugin ID associated with this question answer type.' + uuid: + type: string + label: 'UUID' + description: 'The universally unique identifier (UUID) for this question answer type.' + +quiz_maker.question_response_type.*: + type: config_entity + label: 'Question Response Type' + mapping: + id: + type: string + label: 'Machine Name' + description: 'The machine-readable ID for the answer response type.' + label: + type: string + label: 'Human-readable Name' + description: 'The human-readable name for the answer response type.' + plugin: + type: string + label: 'Plugin ID' + description: 'The plugin ID associated with this answer response type.' + uuid: + type: string + label: 'UUID' + description: 'The universally unique identifier (UUID) for this answer response type.' + +quiz_maker.quiz_type.*: + type: config_entity + label: 'Quiz type config' + mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' + uuid: + type: string + +quiz_maker.question_type.*: + type: config_entity + label: 'Question type config' + mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' + uuid: + type: string + plugin: + type: string + answer_type: + type: string + response_type: + type: string + diff --git a/quiz_maker.info.yml b/quiz_maker.info.yml index 2191c8c61110d19109b8ee5eb6891b2204f32a20..e1339aab1bb3d6ac8d992c9487324efc9743ea3f 100644 --- a/quiz_maker.info.yml +++ b/quiz_maker.info.yml @@ -16,3 +16,4 @@ dependencies: - paragraphs:paragraphs - addtoany:addtoany - update_helper:update_helper + - drupal:taxonomy diff --git a/quiz_maker.module b/quiz_maker.module index 32ef930fbaaf0ded74e7e4a8b9a871ee2fb8ca05..019db1b8e4cd10e0075986bda3bfa07fbc5547ae 100644 --- a/quiz_maker.module +++ b/quiz_maker.module @@ -21,6 +21,8 @@ use Drupal\quiz_maker\Entity\QuestionAnswer; use Drupal\quiz_maker\Entity\QuestionType; use Drupal\quiz_maker\Entity\QuizResultFeedbackParagraph; use Drupal\quiz_maker\Entity\QuizResultType; +use Drupal\quiz_maker\Plugin\QuizMaker\QuestionAnswerPluginInterface; +use Drupal\quiz_maker\Plugin\QuizMaker\QuestionPluginInterface; use Drupal\quiz_maker\QuizInterface; use Drupal\quiz_maker\QuizResultInterface; use Drupal\taxonomy\TermInterface; @@ -465,7 +467,7 @@ function quiz_maker_entity_presave(EntityInterface $entity): void { if ($entity instanceof Question) { $question_type = QuestionType::load($entity->bundle()); $question_instance = $entity->getPluginInstance(); - if (!$question_instance->getAnswers()) { + if ($question_instance instanceof QuestionPluginInterface && !$question_instance->getAnswers()) { $bundle = $question_type->getAnswerType(); $default_answers_data = $entity->getDefaultAnswersData(); foreach ($default_answers_data as $answer_data) { @@ -500,6 +502,10 @@ function quiz_maker_entity_presave(EntityInterface $entity): void { if ($entity instanceof QuestionAnswer) { $answer_instance = $entity->getPluginInstance(); + if (!$answer_instance instanceof QuestionAnswerPluginInterface) { + return; + } + if ($answer_instance->isAlwaysCorrect()) { $answer_instance->setCorrect(TRUE); } @@ -609,6 +615,9 @@ function quiz_maker_entity_base_field_info_alter(&$fields, EntityTypeInterface $ ->setDisplayOptions('form', [ 'type' => 'text_textarea', 'weight' => 10, + 'settings' => [ + 'rows' => 5, + ], ]) ->setDisplayConfigurable('form', TRUE) ->setDisplayOptions('view', [ diff --git a/src/Entity/Question.php b/src/Entity/Question.php index 50cdbfefb5cb86200653253a3488a72cf6712f8a..9ed5fdc1a9c01f58ce8c941ee057bcf08963fd45 100644 --- a/src/Entity/Question.php +++ b/src/Entity/Question.php @@ -280,7 +280,7 @@ class Question extends RevisionableContentEntityBase implements QuestionInterfac * {@inheritDoc} */ public function getQuestion(): ?string { - return $this->getPluginInstance()->getQuestion(); + return $this->getPluginInstance()?->getQuestion(); } /** @@ -300,15 +300,15 @@ class Question extends RevisionableContentEntityBase implements QuestionInterfac /** * {@inheritDoc} */ - public function getMaxScore(): int { - return $this->getPluginInstance()->getMaxScore(); + public function getMaxScore(): ?int { + return $this->getPluginInstance()?->getMaxScore(); } /** * {@inheritDoc} */ public function getTag(): ?TermInterface { - return $this->getPluginInstance()->getTag(); + return $this->getPluginInstance()?->getTag(); } /** diff --git a/src/Entity/Quiz.php b/src/Entity/Quiz.php index 8e2c74ec1fdfe0a78e9c9ed5c986ceb98910039c..6e31743e6a2b279fbda45bf6ae27d0d7add9e451 100644 --- a/src/Entity/Quiz.php +++ b/src/Entity/Quiz.php @@ -227,7 +227,11 @@ class Quiz extends RevisionableContentEntityBase implements QuizInterface { ]) ->setDisplayConfigurable('form', TRUE) ->setDisplayOptions('view', [ + 'type' => 'daterange_default', 'weight' => 5, + 'settings' => [ + 'separator' => '-', + ], ]) ->setDisplayConfigurable('view', TRUE); @@ -356,7 +360,11 @@ class Quiz extends RevisionableContentEntityBase implements QuizInterface { ]) ->setDisplayConfigurable('form', TRUE) ->setDisplayOptions('view', [ + 'type' => 'time_limit', 'weight' => 6, + 'settings' => [ + 'time_format' => 'H:i:s', + ], ]) ->setDisplayConfigurable('view', TRUE); diff --git a/src/Entity/QuizResult.php b/src/Entity/QuizResult.php index 3a1044d89add94d0d414e92b9de32d85e696ecad..f19aeef5e2a064e954d9fd5b62859dc5bdec1a90 100644 --- a/src/Entity/QuizResult.php +++ b/src/Entity/QuizResult.php @@ -160,6 +160,9 @@ class QuizResult extends ContentEntityBase implements QuizResultInterface { ->setDisplayOptions('view', [ 'type' => 'question_response_formatter', 'weight' => 6, + 'settings' => [ + 'list_style' => 'Number with bracket', + ], ]) ->setDisplayConfigurable('view', TRUE); @@ -328,11 +331,11 @@ class QuizResult extends ContentEntityBase implements QuizResultInterface { * @param \Drupal\quiz_maker\QuizResultInterface $quiz_result * The order. * - * @return string + * @return ?string * The workflow ID. */ - public static function getWorkflowId(QuizResultInterface $quiz_result): string { - return QuizResultType::load($quiz_result->bundle())->getWorkflowId(); + public static function getWorkflowId(QuizResultInterface $quiz_result): ?string { + return QuizResultType::load($quiz_result->bundle())?->getWorkflowId(); } /** diff --git a/src/Plugin/Field/FieldFormatter/QuestionCountFormatter.php b/src/Plugin/Field/FieldFormatter/QuestionCountFormatter.php index 8cdcd268ce37b7f3b66c99292c923f534319ab59..5847f87436d7d1c9a3400f4edf86a542b14a3a9e 100644 --- a/src/Plugin/Field/FieldFormatter/QuestionCountFormatter.php +++ b/src/Plugin/Field/FieldFormatter/QuestionCountFormatter.php @@ -15,7 +15,7 @@ use Drupal\Core\Field\FormatterBase; * field_types = {"entity_reference", "entity_reference_revisions"}, * ) */ -final class QuestionCountFormatter extends FormatterBase { +class QuestionCountFormatter extends FormatterBase { /** * {@inheritdoc} diff --git a/src/Plugin/Field/FieldFormatter/QuestionResponseFormatter.php b/src/Plugin/Field/FieldFormatter/QuestionResponseFormatter.php index 5be2436f6453c6d5932ec5916ed073c32a4a4314..0ad1ee6dab27285b701dda7173598b3c3e04905b 100644 --- a/src/Plugin/Field/FieldFormatter/QuestionResponseFormatter.php +++ b/src/Plugin/Field/FieldFormatter/QuestionResponseFormatter.php @@ -19,7 +19,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * field_types = {"entity_reference", "entity_reference_revisions"}, * ) */ -final class QuestionResponseFormatter extends FormatterBase { +class QuestionResponseFormatter extends FormatterBase { /** * Constructs a new QuestionResponseFormatter object. diff --git a/src/Plugin/Field/FieldFormatter/ScoreFieldFormatter.php b/src/Plugin/Field/FieldFormatter/ScoreFieldFormatter.php index 62910540487057820f5cdf422f00455360010c14..d1d43dd46e30814725465416d0c3cb6d61a9aaac 100644 --- a/src/Plugin/Field/FieldFormatter/ScoreFieldFormatter.php +++ b/src/Plugin/Field/FieldFormatter/ScoreFieldFormatter.php @@ -15,7 +15,7 @@ use Drupal\Core\Form\FormStateInterface; * field_types = {"integer"}, * ) */ -final class ScoreFieldFormatter extends FormatterBase { +class ScoreFieldFormatter extends FormatterBase { /** * {@inheritdoc} diff --git a/src/Plugin/Field/FieldFormatter/TimeLimitFormatter.php b/src/Plugin/Field/FieldFormatter/TimeLimitFormatter.php index 4cc2acf4fd97da47388dffd034a42998fc053a21..dd770023e9e813ab4f3c8551d59939e4a07c73a7 100644 --- a/src/Plugin/Field/FieldFormatter/TimeLimitFormatter.php +++ b/src/Plugin/Field/FieldFormatter/TimeLimitFormatter.php @@ -19,7 +19,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * field_types = {"integer"}, * ) */ -final class TimeLimitFormatter extends FormatterBase { +class TimeLimitFormatter extends FormatterBase { /** * Constructs a new TimeLimitFormatter object. diff --git a/src/QuestionInterface.php b/src/QuestionInterface.php index fc2232ba2bf01ee3af04444cd9cede30cc7b7d1d..6d14353e44217f934e4e400b44c8d32c2caf8f6a 100644 --- a/src/QuestionInterface.php +++ b/src/QuestionInterface.php @@ -119,10 +119,10 @@ interface QuestionInterface { /** * Get max score. * - * @return int + * @return ?int * The score. */ - public function getMaxScore(): int; + public function getMaxScore(): ?int; /** * Get default answers. diff --git a/tests/src/Functional/QuizAnonymousTest.php b/tests/src/Functional/QuizAnonymousTest.php new file mode 100644 index 0000000000000000000000000000000000000000..83343bda3c77d10acb5a37270f6d9d37fa9bffb8 --- /dev/null +++ b/tests/src/Functional/QuizAnonymousTest.php @@ -0,0 +1,158 @@ +<?php + +namespace Drupal\Tests\quiz_maker\Functional; + +use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\quiz_maker\Entity\Question; +use Drupal\quiz_maker\Entity\QuestionAnswer; +use Drupal\quiz_maker\Entity\Quiz; + +/** + * Test basic anonymous quiz taking. + * + * @group quiz_maker + */ +class QuizAnonymousTest extends QuizTestBase { + + use StringTranslationTrait; + + /** + * Test taking quiz by anonymous user. + */ + public function testAnonymousQuizTake() { + // Login as our privileged user. + $this->drupalLogin($this->admin); + // Create quiz. + $multiple_answer1 = QuestionAnswer::create([ + 'bundle' => 'multiple_choice_answer', + 'label' => 'Answer 1', + 'answer' => 'Answer 1', + 'is_correct' => TRUE, + ]); + + $multiple_answer1->save(); + + $multiple_answer2 = QuestionAnswer::create([ + 'bundle' => 'multiple_choice_answer', + 'label' => 'Answer 2', + 'answer' => 'Answer 2', + 'is_correct' => TRUE, + ]); + + $multiple_answer2->save(); + + $multiple_answer3 = QuestionAnswer::create([ + 'bundle' => 'multiple_choice_answer', + 'label' => 'Answer 3', + 'answer' => 'Answer 3', + 'is_correct' => FALSE, + ]); + + $multiple_answer3->save(); + + $multiple_answer4 = QuestionAnswer::create([ + 'bundle' => 'multiple_choice_answer', + 'label' => 'Answer 4', + 'answer' => 'Answer 4', + 'is_correct' => FALSE, + ]); + + $multiple_answer4->save(); + + $multiple_question1 = Question::create([ + 'bundle' => 'multiple_choice_question', + 'label' => 'Multiple Choice Question', + 'description' => 'Multiple Choice Question 1', + 'question' => 'Multiple Choice Question 1?', + 'response_type' => 'multiple_choice_response', + 'max_score' => 100, + 'answers' => [$multiple_answer1, $multiple_answer2, $multiple_answer3, $multiple_answer4], + ]); + + $multiple_question1->save(); + + $multiple_answer5 = QuestionAnswer::create([ + 'bundle' => 'multiple_choice_answer', + 'label' => 'Answer 5', + 'answer' => 'Answer 5', + 'is_correct' => TRUE, + ]); + + $multiple_answer5->save(); + + $multiple_answer6 = QuestionAnswer::create([ + 'bundle' => 'multiple_choice_answer', + 'label' => 'Answer 6', + 'answer' => 'Answer 6', + 'is_correct' => TRUE, + ]); + + $multiple_answer6->save(); + + $multiple_answer7 = QuestionAnswer::create([ + 'bundle' => 'multiple_choice_answer', + 'label' => 'Answer 7', + 'answer' => 'Answer 7', + 'is_correct' => TRUE, + ]); + + $multiple_answer7->save(); + + $multiple_answer8 = QuestionAnswer::create([ + 'bundle' => 'multiple_choice_answer', + 'label' => 'Answer 8', + 'answer' => 'Answer 8', + 'is_correct' => TRUE, + ]); + + $multiple_answer8->save(); + + $multiple_question2 = Question::create([ + 'bundle' => 'multiple_choice_question', + 'label' => 'Multiple Choice Question', + 'description' => 'Multiple Choice Question 2', + 'question' => 'Multiple Choice Question 2?', + 'response_type' => 'multiple_choice_response', + 'max_score' => 100, + 'answers' => [$multiple_answer5, $multiple_answer6, $multiple_answer7, $multiple_answer8], + ]); + + $multiple_question1->save(); + + $quiz = Quiz::create([ + 'bundle' => 'standard', + 'label' => 'Test quiz', + 'description' => 'Empty quiz', + 'result_type' => 'standard', + 'attempts' => 5, + 'questions' => [$multiple_question1, $multiple_question2], + ]); + + $quiz->save(); + + // Logout. + $this->drupalLogout(); + + // Take the quiz, make sure we can view and click the link to start. + $this->drupalGet("quiz/{$quiz->id()}"); + $this->clickLink('Take quiz'); + $this->drupalGet("quiz/{$quiz->id()}/take"); + + $this->submitForm([ + "_{$multiple_question1->id()}[{$multiple_answer1->id()}]" => '1', + ], (string) $this->t('Next')); + $this->submitForm([ + "_{$multiple_question2->id()}[{$multiple_answer5->id()}]" => '1', + ], (string) $this->t('Finish')); + + $this->assertSession()->pageTextContains($this->t('Result of "Test quiz"')); + $this->assertSession()->elementContains('css', '.field--name-score', '0%'); + $this->assertSession()->elementContains('css', '.field--name-passed', 'No'); + $this->assertSession()->pageTextContains('Question response'); + $this->assertSession()->pageTextContains('Multiple Choice Question 1'); + $this->assertSession()->pageTextContains('Multiple Choice Question 2'); + $this->assertSession()->pageTextContains('Take quiz again'); + $this->assertSession()->pageTextContains('Go back to quiz'); + } + +} diff --git a/tests/src/Functional/QuizTestBase.php b/tests/src/Functional/QuizTestBase.php new file mode 100644 index 0000000000000000000000000000000000000000..826bb2be5f8e14d374bcd6dc099cacc402c843c2 --- /dev/null +++ b/tests/src/Functional/QuizTestBase.php @@ -0,0 +1,86 @@ +<?php + +namespace Drupal\Tests\quiz_maker\Functional; + +use Drupal\Tests\BrowserTestBase; +use Drupal\Tests\quiz_maker\Traits\QuizCreateTrait; + +/** + * Base test class for Quiz. + */ +class QuizTestBase extends BrowserTestBase { + + use QuizCreateTrait; + + /** + * Set to TRUE to strict check all configuration saved. + * + * @var bool + * @see ConfigSchemaChecker + * + * @todo Remove once there is 8.x-3.0-alpha6 which fixes a schema issue. + */ + protected $strictConfigSchema = FALSE; + + /** + * The theme to install as the default for testing. + * + * Defaults to the install profile's default theme, if it specifies any. + * + * @var string + */ + protected $defaultTheme = 'claro'; + + /** + * Modules to install. + * + * @var array + */ + protected static $modules = ['quiz_maker']; + + /** + * Normal User account. + * + * @var \Drupal\user\Entity\User + */ + protected $user; + + /** + * Administration user account. + * + * @var \Drupal\user\Entity\User + */ + protected $admin; + + + /** + * {@inheritdoc} + */ + public function setUp($admin_permissions = [], $user_permissions = []): void { + parent::setUp(); + + $admin_permissions = array_merge($admin_permissions, [ + 'administer question types', + 'administer quiz types', + 'administer question_answer types', + 'administer quiz_result types', + 'administer question_response types', + 'administer quiz_result', + ]); + + $user_permissions = array_merge($user_permissions, [ + 'view all question revisions', + 'view all quiz revisions', + 'view question', + 'view question revision', + 'view quiz', + 'view quiz revision', + 'view quiz_result', + 'take quiz', + ]); + + $this->admin = $this->drupalCreateUser(array_unique($admin_permissions)); + $this->user = $this->drupalCreateUser(array_unique($user_permissions)); + } + +} diff --git a/tests/src/Kernel/QuestionAnswerKernelTest.php b/tests/src/Kernel/QuestionAnswerKernelTest.php new file mode 100644 index 0000000000000000000000000000000000000000..67676aeea9bb34b551428759c539c627eb15d902 --- /dev/null +++ b/tests/src/Kernel/QuestionAnswerKernelTest.php @@ -0,0 +1,212 @@ +<?php + +namespace Drupal\Tests\quiz_maker\Kernel; + +use Drupal\quiz_maker\Entity\QuestionAnswer; +use Drupal\Tests\quiz_maker\Traits\QuestionAnswerCreateTrait; + +/** + * Tests creation of Quiz Question Answers. + * + * @group quiz_maker + */ +class QuestionAnswerKernelTest extends QuizKernelTestBase { + + use QuestionAnswerCreateTrait; + + /** + * Tests the creation boolean Answer. + */ + public function testBooleanAnswerCreate() { + $answer = $this->createBooleanAnswer(); + + $this->assertEquals('Boolean answer', $answer->label()); + $this->assertEquals('boolean_answer', $answer->bundle()); + $this->assertEquals('Boolean answer', $answer->get('answer')->value); + $this->assertEquals(FALSE, $answer->get('is_correct')->value); + } + + /** + * Tests the updating boolean Answer. + */ + public function testBooleanAnswerUpdate() { + $answer = $this->createBooleanAnswer(); + + $answer->set('answer', 'Updated Boolean Answer'); + $answer->set('is_correct', TRUE); + + $this->assertEquals('Updated Boolean Answer', $answer->get('answer')->value); + $this->assertEquals(TRUE, $answer->get('is_correct')->value); + } + + /** + * Tests the deleting boolean Answer. + */ + public function testBooleanAnswerDelete() { + $answer = $this->createBooleanAnswer(); + + $answer_id = $answer->id(); + $answer->delete(); + + // Assert that the quiz no longer exists in the database. + $deleted_answer = QuestionAnswer::load($answer_id); + $this->assertNull($deleted_answer); + } + + /** + * Tests the creation direct Answer. + */ + public function testDirectAnswerCreate() { + $answer = $this->createDirectAnswer(); + + $this->assertEquals('Direct answer', $answer->label()); + $this->assertEquals('direct_answer', $answer->bundle()); + $this->assertEquals('Direct answer', $answer->get('answer')->value); + $this->assertEquals(FALSE, $answer->get('is_correct')->value); + } + + /** + * Tests the updating direct Answer. + */ + public function testDirectAnswerUpdate() { + $answer = $this->createDirectAnswer(); + + $answer->set('answer', 'Updated Direct Answer'); + $answer->set('is_correct', TRUE); + + $this->assertEquals('Updated Direct Answer', $answer->get('answer')->value); + $this->assertEquals(TRUE, $answer->get('is_correct')->value); + } + + /** + * Tests the deleting direct Answer. + */ + public function testDirectAnswerDelete() { + $answer = $this->createDirectAnswer(); + + $answer_id = $answer->id(); + $answer->delete(); + + // Assert that the quiz no longer exists in the database. + $deleted_answer = QuestionAnswer::load($answer_id); + $this->assertNull($deleted_answer); + } + + /** + * Tests the creation of Matching Answer. + */ + public function testMatchingAnswerCreate() { + $answer = $this->createMatchingAnswer(); + + $this->assertEquals('Matching answer', $answer->label()); + $this->assertEquals('matching_answer', $answer->bundle()); + $this->assertEquals('Matching answer', $answer->get('answer')->value); + $this->assertEquals(FALSE, $answer->get('is_correct')->value); + } + + /** + * Tests the updating of Matching Answer. + */ + public function testMatchingAnswerUpdate() { + $answer = $this->createMatchingAnswer(); + + $answer->set('answer', 'Updated Matching Answer'); + $answer->set('is_correct', TRUE); + + $this->assertEquals('Updated Matching Answer', $answer->get('answer')->value); + $this->assertEquals(TRUE, $answer->get('is_correct')->value); + } + + /** + * Tests the deleting of Matching Answer. + */ + public function testMatchingAnswerDelete() { + $answer = $this->createMatchingAnswer(); + + $answer_id = $answer->id(); + $answer->delete(); + + // Assert that the matching answer no longer exists in the database. + $deleted_answer = QuestionAnswer::load($answer_id); + $this->assertNull($deleted_answer); + } + + /** + * Tests the creation of Multiple Choice Answer. + */ + public function testMultipleChoiceAnswerCreate() { + $answer = $this->createMultipleChoiceAnswer(); + + $this->assertEquals('Multiple Choice answer', $answer->label()); + $this->assertEquals('multiple_choice_answer', $answer->bundle()); + $this->assertEquals('Multiple Choice answer', $answer->get('answer')->value); + $this->assertEquals(FALSE, $answer->get('is_correct')->value); + } + + /** + * Tests the updating of Multiple Choice Answer. + */ + public function testMultipleChoiceAnswerUpdate() { + $answer = $this->createMultipleChoiceAnswer(); + + $answer->set('answer', 'Updated Multiple Choice Answer'); + $answer->set('is_correct', TRUE); + + $this->assertEquals('Updated Multiple Choice Answer', $answer->get('answer')->value); + $this->assertEquals(TRUE, $answer->get('is_correct')->value); + } + + /** + * Tests the deleting of Multiple Choice Answer. + */ + public function testMultipleChoiceAnswerDelete() { + $answer = $this->createMultipleChoiceAnswer(); + + $answer_id = $answer->id(); + $answer->delete(); + + // Assert that the multiple choice answer no longer exists in the database. + $deleted_answer = QuestionAnswer::load($answer_id); + $this->assertNull($deleted_answer); + } + + /** + * Tests the creation of Single Choice Answer. + */ + public function testSingleChoiceAnswerCreate() { + $answer = $this->createSingleChoiceAnswer(); + + $this->assertEquals('Single Choice answer', $answer->label()); + $this->assertEquals('single_choice_answer', $answer->bundle()); + $this->assertEquals('Single Choice answer', $answer->get('answer')->value); + $this->assertEquals(FALSE, $answer->get('is_correct')->value); + } + + /** + * Tests the updating of Single Choice Answer. + */ + public function testSingleChoiceAnswerUpdate() { + $answer = $this->createSingleChoiceAnswer(); + + $answer->set('answer', 'Updated Single Choice Answer'); + $answer->set('is_correct', TRUE); + + $this->assertEquals('Updated Single Choice Answer', $answer->get('answer')->value); + $this->assertEquals(TRUE, $answer->get('is_correct')->value); + } + + /** + * Tests the deleting of Single Choice Answer. + */ + public function testSingleChoiceAnswerDelete() { + $answer = $this->createSingleChoiceAnswer(); + + $answer_id = $answer->id(); + $answer->delete(); + + // Assert that the single choice answer no longer exists in the database. + $deleted_answer = QuestionAnswer::load($answer_id); + $this->assertNull($deleted_answer); + } + +} diff --git a/tests/src/Kernel/QuestionKernelTest.php b/tests/src/Kernel/QuestionKernelTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4df74e35f5349a1c31e4243996b96d3fd41a131b --- /dev/null +++ b/tests/src/Kernel/QuestionKernelTest.php @@ -0,0 +1,212 @@ +<?php + +namespace Drupal\Tests\quiz_maker\Kernel; + +use Drupal\quiz_maker\Entity\Question; +use Drupal\Tests\quiz_maker\Traits\QuestionCreateTrait; + +/** + * Tests creation of Quiz Question. + * + * @group quiz_maker + */ +class QuestionKernelTest extends QuizKernelTestBase { + + use QuestionCreateTrait; + + /** + * Tests the creation boolean Question. + */ + public function testBooleanQuestionCreate() { + $question = $this->createBooleanQuestion(); + + $this->assertEquals('Boolean Question', $question->label()); + $this->assertEquals('boolean_question', $question->bundle()); + $this->assertEquals('Boolean Question?', $question->get('question')->value); + $this->assertEquals(100, $question->get('max_score')->value); + } + + /** + * Tests the creation boolean Question. + */ + public function testBooleanQuestionUpdate() { + $question = $this->createBooleanQuestion(); + + $question->set('question', 'Updated Boolean Question?'); + $question->set('max_score', 200); + + $this->assertEquals('Updated Boolean Question?', $question->get('question')->value); + $this->assertEquals(200, $question->get('max_score')->value); + } + + /** + * Tests the creation boolean Question. + */ + public function testBooleanQuestionDelete() { + $question = $this->createBooleanQuestion(); + + $question_id = $question->id(); + $question->delete(); + + // Assert that the quiz no longer exists in the database. + $deleted_quiz = Question::load($question_id); + $this->assertNull($deleted_quiz); + } + + /** + * Tests the creation direct Question. + */ + public function testDirectQuestionCreate() { + $question = $this->createDirectQuestion(); + + $this->assertEquals('Direct Question', $question->label()); + $this->assertEquals('direct_question', $question->bundle()); + $this->assertEquals('Direct Question?', $question->get('question')->value); + $this->assertEquals(100, $question->get('max_score')->value); + } + + /** + * Tests the creation direct Question. + */ + public function testDirectQuestionUpdate() { + $question = $this->createDirectQuestion(); + + $question->set('question', 'Updated Direct Question?'); + $question->set('max_score', 200); + + $this->assertEquals('Updated Direct Question?', $question->get('question')->value); + $this->assertEquals(200, $question->get('max_score')->value); + } + + /** + * Tests the creation direct Question. + */ + public function testDirectQuestionDelete() { + $question = $this->createDirectQuestion(); + + $question_id = $question->id(); + $question->delete(); + + // Assert that the question no longer exists in the database. + $deleted_question = Question::load($question_id); + $this->assertNull($deleted_question); + } + + /** + * Tests the creation Matching Question. + */ + public function testMatchingQuestionCreate() { + $question = $this->createMatchingQuestion(); + + $this->assertEquals('Matching Question', $question->label()); + $this->assertEquals('matching_question', $question->bundle()); + $this->assertEquals('Matching Question?', $question->get('question')->value); + $this->assertEquals(100, $question->get('max_score')->value); + } + + /** + * Tests the creation Matching Question. + */ + public function testMatchingQuestionUpdate() { + $question = $this->createMatchingQuestion(); + + $question->set('question', 'Updated Matching Question?'); + $question->set('max_score', 200); + + $this->assertEquals('Updated Matching Question?', $question->get('question')->value); + $this->assertEquals(200, $question->get('max_score')->value); + } + + /** + * Tests the creation Matching Question. + */ + public function testMatchingQuestionDelete() { + $question = $this->createMatchingQuestion(); + + $question_id = $question->id(); + $question->delete(); + + // Assert that the question no longer exists in the database. + $deleted_question = Question::load($question_id); + $this->assertNull($deleted_question); + } + + /** + * Tests the creation Multiple Choice Question. + */ + public function testMultipleChoiceQuestionCreate() { + $question = $this->createMultipleChoiceQuestion(); + + $this->assertEquals('Multiple Choice Question', $question->label()); + $this->assertEquals('multiple_choice_question', $question->bundle()); + $this->assertEquals('Multiple Choice Question?', $question->get('question')->value); + $this->assertEquals(100, $question->get('max_score')->value); + } + + /** + * Tests the creation Multiple Choice Question. + */ + public function testMultipleChoiceQuestionUpdate() { + $question = $this->createMultipleChoiceQuestion(); + + $question->set('question', 'Updated Multiple Choice Question?'); + $question->set('max_score', 200); + + $this->assertEquals('Updated Multiple Choice Question?', $question->get('question')->value); + $this->assertEquals(200, $question->get('max_score')->value); + } + + /** + * Tests the creation MultipleChoice Question. + */ + public function testMultipleChoiceQuestionDelete() { + $question = $this->createMultipleChoiceQuestion(); + + $question_id = $question->id(); + $question->delete(); + + // Assert that the question no longer exists in the database. + $deleted_question = Question::load($question_id); + $this->assertNull($deleted_question); + } + + /** + * Tests the creation Single Choice Question. + */ + public function testSingleChoiceQuestionCreate() { + $question = $this->createSingleChoiceQuestion(); + + $this->assertEquals('Single Choice Question', $question->label()); + $this->assertEquals('single_choice_question', $question->bundle()); + $this->assertEquals('Single Choice Question?', $question->get('question')->value); + $this->assertEquals(100, $question->get('max_score')->value); + } + + /** + * Tests the creation Single Choice Question. + */ + public function testSingleChoiceQuestionUpdate() { + $question = $this->createSingleChoiceQuestion(); + + $question->set('question', 'Updated Single Choice Question?'); + $question->set('max_score', 200); + + $this->assertEquals('Updated Single Choice Question?', $question->get('question')->value); + $this->assertEquals(200, $question->get('max_score')->value); + } + + /** + * Tests the creation Single Choice Question. + */ + public function testSingleChoiceQuestionDelete() { + $question = $this->createSingleChoiceQuestion(); + + $question_id = $question->id(); + $question->delete(); + + // Assert that the question no longer exists in the database. + $deleted_question = Question::load($question_id); + $this->assertNull($deleted_question); + } + +} diff --git a/tests/src/Kernel/QuestionResponseKernelTest.php b/tests/src/Kernel/QuestionResponseKernelTest.php new file mode 100644 index 0000000000000000000000000000000000000000..744656bac915c4dd2f97280b599a33bb329068fd --- /dev/null +++ b/tests/src/Kernel/QuestionResponseKernelTest.php @@ -0,0 +1,212 @@ +<?php + +namespace Drupal\Tests\quiz_maker\Kernel; + +use Drupal\quiz_maker\Entity\QuestionResponse; +use Drupal\Tests\quiz_maker\Traits\QuestionResponseCreateTrait; + +/** + * Tests creation of Quiz Question Response. + * + * @group quiz_maker + */ +class QuestionResponseKernelTest extends QuizKernelTestBase { + + use QuestionResponseCreateTrait; + + /** + * Tests the creation boolean Answer. + */ + public function testBooleanResponseCreate() { + $answer = $this->createBooleanResponse(); + + $this->assertEquals('Boolean response', $answer->label()); + $this->assertEquals('boolean_response', $answer->bundle()); + $this->assertEquals('Boolean response', $answer->get('label')->value); + $this->assertEquals(FALSE, $answer->get('is_correct')->value); + } + + /** + * Tests the updating boolean response. + */ + public function testBooleanResponseUpdate() { + $answer = $this->createBooleanResponse(); + + $answer->set('label', 'Updated Boolean Answer'); + $answer->set('is_correct', TRUE); + + $this->assertEquals('Updated Boolean Answer', $answer->get('label')->value); + $this->assertEquals(TRUE, $answer->get('is_correct')->value); + } + + /** + * Tests the deleting boolean response. + */ + public function testBooleanResponseDelete() { + $response = $this->createBooleanResponse(); + + $response_id = $response->id(); + $response->delete(); + + // Assert that the quiz no longer exists in the database. + $deleted_answer = QuestionResponse::load($response_id); + $this->assertNull($deleted_answer); + } + + /** + * Tests the creation of Direct response. + */ + public function testDirectResponseCreate() { + $response = $this->createDirectResponse(); + + $this->assertEquals('Direct response', $response->label()); + $this->assertEquals('direct_response', $response->bundle()); + $this->assertEquals('Direct response', $response->get('label')->value); + $this->assertEquals(FALSE, $response->get('is_correct')->value); + } + + /** + * Tests the updating of Direct response. + */ + public function testDirectResponseUpdate() { + $response = $this->createDirectResponse(); + + $response->set('label', 'Updated Direct Answer'); + $response->set('is_correct', TRUE); + + $this->assertEquals('Updated Direct Answer', $response->get('label')->value); + $this->assertEquals(TRUE, $response->get('is_correct')->value); + } + + /** + * Tests the deleting of Direct response. + */ + public function testDirectResponseDelete() { + $response = $this->createDirectResponse(); + + $response_id = $response->id(); + $response->delete(); + + // Assert that the response no longer exists in the database. + $deleted_response = QuestionResponse::load($response_id); + $this->assertNull($deleted_response); + } + + /** + * Tests the creation of Matching response. + */ + public function testMatchingResponseCreate() { + $response = $this->createMatchingResponse(); + + $this->assertEquals('Matching response', $response->label()); + $this->assertEquals('matching_choice_response', $response->bundle()); + $this->assertEquals('Matching response', $response->get('label')->value); + $this->assertEquals(FALSE, $response->get('is_correct')->value); + } + + /** + * Tests the updating of Matching response. + */ + public function testMatchingResponseUpdate() { + $response = $this->createMatchingResponse(); + + $response->set('label', 'Updated Matching Answer'); + $response->set('is_correct', TRUE); + + $this->assertEquals('Updated Matching Answer', $response->get('label')->value); + $this->assertEquals(TRUE, $response->get('is_correct')->value); + } + + /** + * Tests the deleting of Matching response. + */ + public function testMatchingResponseDelete() { + $response = $this->createMatchingResponse(); + + $response_id = $response->id(); + $response->delete(); + + // Assert that the response no longer exists in the database. + $deleted_response = QuestionResponse::load($response_id); + $this->assertNull($deleted_response); + } + + /** + * Tests the creation of Multiple choice response. + */ + public function testMultipleChoiceResponseCreate() { + $response = $this->createMultipleChoiceResponse(); + + $this->assertEquals('Multiple choice response', $response->label()); + $this->assertEquals('multiple_choice_response', $response->bundle()); + $this->assertEquals('Multiple choice response', $response->get('label')->value); + $this->assertEquals(FALSE, $response->get('is_correct')->value); + } + + /** + * Tests the updating of Multiple choice response. + */ + public function testMultipleChoiceResponseUpdate() { + $response = $this->createMultipleChoiceResponse(); + + $response->set('label', 'Updated Multiple Choice Answer'); + $response->set('is_correct', TRUE); + + $this->assertEquals('Updated Multiple Choice Answer', $response->get('label')->value); + $this->assertEquals(TRUE, $response->get('is_correct')->value); + } + + /** + * Tests the deleting of Multiple choice response. + */ + public function testMultipleChoiceResponseDelete() { + $response = $this->createMultipleChoiceResponse(); + + $response_id = $response->id(); + $response->delete(); + + // Assert that the response no longer exists in the database. + $deleted_response = QuestionResponse::load($response_id); + $this->assertNull($deleted_response); + } + + /** + * Tests the creation of Single choice response. + */ + public function testSingleChoiceResponseCreate() { + $response = $this->createSingleChoiceResponse(); + + $this->assertEquals('Single choice response', $response->label()); + $this->assertEquals('single_choice_response', $response->bundle()); + $this->assertEquals('Single choice response', $response->get('label')->value); + $this->assertEquals(FALSE, $response->get('is_correct')->value); + } + + /** + * Tests the updating of Single choice response. + */ + public function testSingleChoiceResponseUpdate() { + $response = $this->createSingleChoiceResponse(); + + $response->set('label', 'Updated Single Choice Answer'); + $response->set('is_correct', TRUE); + + $this->assertEquals('Updated Single Choice Answer', $response->get('label')->value); + $this->assertEquals(TRUE, $response->get('is_correct')->value); + } + + /** + * Tests the deleting of Single choice response. + */ + public function testSingleChoiceResponseDelete() { + $response = $this->createSingleChoiceResponse(); + + $response_id = $response->id(); + $response->delete(); + + // Assert that the response no longer exists in the database. + $deleted_response = QuestionResponse::load($response_id); + $this->assertNull($deleted_response); + } + +} diff --git a/tests/src/Kernel/QuizKernelTest.php b/tests/src/Kernel/QuizKernelTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d7165e3afc84e0d22de0c09a8d6da2eb5bfd3a0e --- /dev/null +++ b/tests/src/Kernel/QuizKernelTest.php @@ -0,0 +1,88 @@ +<?php + +namespace Drupal\Tests\quiz_maker\Kernel; + +use Drupal\quiz_maker\Entity\Quiz; + +/** + * Tests creation of Quiz. + * + * @group quiz_maker + */ +class QuizKernelTest extends QuizKernelTestBase { + + /** + * Tests the creation Quiz. + */ + public function testStandardQuizCreation() { + $quiz = Quiz::create([ + 'bundle' => 'standard', + 'label' => 'Empty quiz', + 'description' => 'Empty quiz', + 'result_type' => 'standard', + 'manual_assessment' => FALSE, + 'allow_backwards_navigation' => FALSE, + 'allow_jumping' => FALSE, + 'allow_skipping' => FALSE, + 'allow_changing_answers' => FALSE, + 'attempts' => 5, + ]); + + $quiz->save(); + + $this->assertEquals('Empty quiz', $quiz->label()); + $this->assertEquals(FALSE, $quiz->requireManualAssessment()); + $this->assertEquals(FALSE, $quiz->allowBackwardNavigation()); + $this->assertEquals(FALSE, $quiz->allowJumping()); + $this->assertEquals(FALSE, $quiz->allowSkipping()); + $this->assertEquals(FALSE, $quiz->allowChangeAnswer()); + $this->assertEquals(5, $quiz->getAllowedAttempts()); + } + + /** + * Tests the updating Quiz. + */ + public function testStandardQuizUpdate() { + $quiz = Quiz::create([ + 'bundle' => 'standard', + 'label' => 'Empty quiz', + 'description' => 'Empty quiz', + 'result_type' => 'standard', + 'attempts' => 5, + ]); + + $quiz->save(); + + $quiz->set('label', 'Updated quiz'); + $quiz->set('attempts', 6); + $quiz->save(); + + $updated_quiz = Quiz::load($quiz->id()); + $this->assertEquals('Updated quiz', $updated_quiz->label()); + $this->assertEquals(6, $updated_quiz->getAllowedAttempts()); + } + + /** + * Tests the deleting Quiz. + */ + public function testStandardQuizDelete() { + $quiz = Quiz::create([ + 'bundle' => 'standard', + 'label' => 'Empty quiz', + 'description' => 'Empty quiz', + 'result_type' => 'standard', + 'attempts' => 5, + ]); + + $quiz->save(); + + // Get the quiz ID and delete it. + $quiz_id = $quiz->id(); + $quiz->delete(); + + // Assert that the quiz no longer exists in the database. + $deleted_quiz = Quiz::load($quiz_id); + $this->assertNull($deleted_quiz); + } + +} diff --git a/tests/src/Kernel/QuizKernelTestBase.php b/tests/src/Kernel/QuizKernelTestBase.php new file mode 100644 index 0000000000000000000000000000000000000000..3db0e3e0da353bf1700e19bbb774062db1dd4b95 --- /dev/null +++ b/tests/src/Kernel/QuizKernelTestBase.php @@ -0,0 +1,59 @@ +<?php + +namespace Drupal\Tests\quiz_maker\Kernel; + +use Drupal\KernelTests\KernelTestBase; +use Drupal\user\Entity\User; + +/** + * Base class for Quiz kernel tests. + */ +abstract class QuizKernelTestBase extends KernelTestBase { + + /** + * Modules to install. + * + * @var array + */ + public static $modules = [ + 'quiz_maker', + 'user', + 'field', + 'text', + 'taxonomy', + 'system', + 'datetime_range', + 'editor', + 'entity_reference_revisions', + 'inline_entity_form', + 'field_group', + 'views_bulk_operations', + 'entity_browser', + 'entity', + 'state_machine', + 'paragraphs', + 'addtoany', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + $this->installEntitySchema('user'); + $this->installEntitySchema('quiz'); + $this->installEntitySchema('question'); + $this->installEntitySchema('question_answer'); + $this->installEntitySchema('question_response'); + $this->installEntitySchema('quiz_result'); + + $this->user = User::create([ + 'name' => 'username', + 'status' => 1, + ]); + $this->user->save(); + $this->container->get('current_user')->setAccount($this->user); + } + +} diff --git a/tests/src/Kernel/QuizResultKernelTest.php b/tests/src/Kernel/QuizResultKernelTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4bfabcb8c92d99c0ba2bfa4cadebee3435d1cdfa --- /dev/null +++ b/tests/src/Kernel/QuizResultKernelTest.php @@ -0,0 +1,76 @@ +<?php + +namespace Drupal\Tests\quiz_maker\Kernel; + +use Drupal\quiz_maker\Entity\QuizResult; + +/** + * Tests creation of Quiz Result. + * + * @group quiz_maker + */ +class QuizResultKernelTest extends QuizKernelTestBase { + + /** + * Tests the creation Quiz Result. + */ + public function testStandardQuizResultCreate() { + $quiz_result = QuizResult::create([ + 'bundle' => 'standard', + 'label' => 'Quiz result test', + 'score' => 1.0, + 'state' => 'completed', + 'attempt' => 1, + ]); + + $quiz_result->save(); + + $this->assertEquals('Quiz result test', $quiz_result->label()); + $this->assertEquals(1.0, $quiz_result->getScore()); + } + + /** + * Tests the updating Quiz. + */ + public function testStandardQuizUpdate() { + $quiz_result = QuizResult::create([ + 'bundle' => 'standard', + 'label' => 'Quiz result test', + 'score' => 1.0, + 'state' => 'completed', + 'attempt' => 1, + ]); + + $quiz_result->save(); + + $quiz_result->set('label', 'Updated Quiz result test'); + $quiz_result->save(); + + $updated_quiz_result = QuizResult::load($quiz_result->id()); + $this->assertEquals('Updated Quiz result test', $updated_quiz_result->label()); + } + + /** + * Tests the deleting Quiz result. + */ + public function testStandardQuizResultDelete() { + $quiz_result = QuizResult::create([ + 'bundle' => 'standard', + 'label' => 'Quiz result test', + 'score' => 1.0, + 'state' => 'completed', + 'attempt' => 1, + ]); + + $quiz_result->save(); + + // Get the quiz ID and delete it. + $quiz_result_id = $quiz_result->id(); + $quiz_result->delete(); + + // Assert that the quiz result no longer exists in the database. + $deleted_quiz = QuizResult::load($quiz_result_id); + $this->assertNull($deleted_quiz); + } + +} diff --git a/tests/src/Traits/QuestionAnswerCreateTrait.php b/tests/src/Traits/QuestionAnswerCreateTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..744d5f18aa232f4c4875402828a298243fd70a7c --- /dev/null +++ b/tests/src/Traits/QuestionAnswerCreateTrait.php @@ -0,0 +1,92 @@ +<?php + +namespace Drupal\Tests\quiz_maker\Traits; + +use Drupal\quiz_maker\Entity\QuestionAnswer; + +/** + * Provide common helper methods for Quiz Question Answers. + */ +trait QuestionAnswerCreateTrait { + + /** + * Create boolean answer. + */ + public function createBooleanAnswer() { + $answer = QuestionAnswer::create([ + 'bundle' => 'boolean_answer', + 'label' => 'Boolean answer', + 'answer' => 'Boolean answer', + 'is_correct' => FALSE, + ]); + + $answer->save(); + + return $answer; + } + + /** + * Create direct answer. + */ + public function createDirectAnswer() { + $answer = QuestionAnswer::create([ + 'bundle' => 'direct_answer', + 'label' => 'Direct answer', + 'answer' => 'Direct answer', + 'is_correct' => FALSE, + ]); + + $answer->save(); + + return $answer; + } + + /** + * Create Matching answer. + */ + public function createMatchingAnswer() { + $answer = QuestionAnswer::create([ + 'bundle' => 'matching_answer', + 'label' => 'Matching answer', + 'answer' => 'Matching answer', + 'is_correct' => FALSE, + ]); + + $answer->save(); + + return $answer; + } + + /** + * Create Multiple Choice answer. + */ + public function createMultipleChoiceAnswer() { + $answer = QuestionAnswer::create([ + 'bundle' => 'multiple_choice_answer', + 'label' => 'Multiple Choice answer', + 'answer' => 'Multiple Choice answer', + 'is_correct' => FALSE, + ]); + + $answer->save(); + + return $answer; + } + + /** + * Create Single Choice answer. + */ + public function createSingleChoiceAnswer() { + $answer = QuestionAnswer::create([ + 'bundle' => 'single_choice_answer', + 'label' => 'Single Choice answer', + 'answer' => 'Single Choice answer', + 'is_correct' => FALSE, + ]); + + $answer->save(); + + return $answer; + } + +} diff --git a/tests/src/Traits/QuestionCreateTrait.php b/tests/src/Traits/QuestionCreateTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..168bbda82d0f178ec838d8235f71195494e908ac --- /dev/null +++ b/tests/src/Traits/QuestionCreateTrait.php @@ -0,0 +1,102 @@ +<?php + +namespace Drupal\Tests\quiz_maker\Traits; + +use Drupal\quiz_maker\Entity\Question; + +/** + * Provide common helper methods for Quiz Questions. + */ +trait QuestionCreateTrait { + + /** + * Create boolean question. + */ + public function createBooleanQuestion() { + $question = Question::create([ + 'bundle' => 'boolean_question', + 'label' => 'Boolean Question', + 'description' => 'Boolean Question', + 'question' => 'Boolean Question?', + 'response_type' => 'boolean_response', + 'max_score' => 100, + ]); + + $question->save(); + + return $question; + } + + /** + * Create direct question. + */ + public function createDirectQuestion() { + $question = Question::create([ + 'bundle' => 'direct_question', + 'label' => 'Direct Question', + 'description' => 'Direct Question', + 'question' => 'Direct Question?', + 'response_type' => 'direct_response', + 'max_score' => 100, + ]); + + $question->save(); + + return $question; + } + + /** + * Create matching question. + */ + public function createMatchingQuestion() { + $question = Question::create([ + 'bundle' => 'matching_question', + 'label' => 'Matching Question', + 'description' => 'Matching Question', + 'question' => 'Matching Question?', + 'response_type' => 'matching_response', + 'max_score' => 100, + ]); + + $question->save(); + + return $question; + } + + /** + * Create multiple choice question. + */ + public function createMultipleChoiceQuestion() { + $question = Question::create([ + 'bundle' => 'multiple_choice_question', + 'label' => 'Multiple Choice Question', + 'description' => 'Multiple Choice Question', + 'question' => 'Multiple Choice Question?', + 'response_type' => 'multiple_choice_response', + 'max_score' => 100, + ]); + + $question->save(); + + return $question; + } + + /** + * Create single choice question. + */ + public function createSingleChoiceQuestion() { + $question = Question::create([ + 'bundle' => 'single_choice_question', + 'label' => 'Single Choice Question', + 'description' => 'Single Choice Question', + 'question' => 'Single Choice Question?', + 'response_type' => 'single_choice_response', + 'max_score' => 100, + ]); + + $question->save(); + + return $question; + } + +} diff --git a/tests/src/Traits/QuestionResponseCreateTrait.php b/tests/src/Traits/QuestionResponseCreateTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..573e0289215c9752a7a1f3359948216a70fd82a7 --- /dev/null +++ b/tests/src/Traits/QuestionResponseCreateTrait.php @@ -0,0 +1,92 @@ +<?php + +namespace Drupal\Tests\quiz_maker\Traits; + +use Drupal\quiz_maker\Entity\QuestionResponse; + +/** + * Provide common helper methods for Quiz Question Answers. + */ +trait QuestionResponseCreateTrait { + + /** + * Create boolean response. + */ + public function createBooleanResponse() { + $answer = QuestionResponse::create([ + 'bundle' => 'boolean_response', + 'label' => 'Boolean response', + 'is_correct' => FALSE, + 'score' => 0.5, + ]); + + $answer->save(); + + return $answer; + } + + /** + * Create direct response. + */ + public function createDirectResponse() { + $answer = QuestionResponse::create([ + 'bundle' => 'direct_response', + 'label' => 'Direct response', + 'is_correct' => FALSE, + 'score' => 0.5, + ]); + + $answer->save(); + + return $answer; + } + + /** + * Create matching response. + */ + public function createMatchingResponse() { + $answer = QuestionResponse::create([ + 'bundle' => 'matching_choice_response', + 'label' => 'Matching response', + 'is_correct' => FALSE, + 'score' => 0.5, + ]); + + $answer->save(); + + return $answer; + } + + /** + * Create multiple choice response. + */ + public function createMultipleChoiceResponse() { + $answer = QuestionResponse::create([ + 'bundle' => 'multiple_choice_response', + 'label' => 'Multiple choice response', + 'is_correct' => FALSE, + 'score' => 0.5, + ]); + + $answer->save(); + + return $answer; + } + + /** + * Create single choice response. + */ + public function createSingleChoiceResponse() { + $answer = QuestionResponse::create([ + 'bundle' => 'single_choice_response', + 'label' => 'Single choice response', + 'is_correct' => FALSE, + 'score' => 0.5, + ]); + + $answer->save(); + + return $answer; + } + +} diff --git a/tests/src/Traits/QuizCreateTrait.php b/tests/src/Traits/QuizCreateTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..8dc3ad6783846039a998028fa46c7c2a526f5af3 --- /dev/null +++ b/tests/src/Traits/QuizCreateTrait.php @@ -0,0 +1,183 @@ +<?php + +namespace Drupal\Tests\quiz_maker\Traits; + +use Drupal\quiz_maker\Entity\Question; +use Drupal\quiz_maker\Entity\QuestionAnswer; +use Drupal\quiz_maker\Entity\Quiz; + +/** + * Provide common helper methods for Quiz creation. + */ +trait QuizCreateTrait { + + /** + * Get multiple choice question with answer. + */ + public function getMultipleChoiceQuestionWithAnswers(): Question { + $answers = []; + + for ($i = 1; $i <= 5; $i++) { + $answer = QuestionAnswer::create([ + 'bundle' => 'multiple_choice_answer', + 'label' => "Answer $i", + 'answer' => "Answer $i", + 'is_correct' => $i % 2 === 0, + ]); + $answer->save(); + $answers[] = $answer; + } + + $question = Question::create([ + 'bundle' => 'multiple_choice_question', + 'label' => 'Multiple Choice Question', + 'description' => 'Multiple Choice Question', + 'question' => 'Multiple Choice Question?', + 'response_type' => 'multiple_choice_response', + 'max_score' => 100, + 'answers' => $answers, + ]); + + $question->save(); + + return $question; + } + + /** + * Get single choice question with answer. + */ + public function getSingleChoiceQuestionWithAnswers(): Question { + $answers = []; + + for ($i = 1; $i <= 5; $i++) { + $answer = QuestionAnswer::create([ + 'bundle' => 'single_choice_answer', + 'label' => "Answer $i", + 'answer' => "Answer $i", + 'is_correct' => $i % 2 === 0, + ]); + $answer->save(); + $answers[] = $answer; + } + + $question = Question::create([ + 'bundle' => 'single_choice_question', + 'label' => 'Single Choice Question', + 'description' => 'Single Choice Question', + 'question' => 'Single Choice Question?', + 'response_type' => 'single_choice_response', + 'max_score' => 100, + 'answers' => $answers, + ]); + + $question->save(); + + return $question; + } + + /** + * Get matching question with answer. + */ + public function getMatchingQuestionWithAnswers(): Question { + $answers = []; + + for ($i = 1; $i <= 5; $i++) { + $answer = QuestionAnswer::create([ + 'bundle' => 'matching_answer', + 'label' => "Answer $i", + 'field_matching_question' => "Question $i", + 'field_matching_answer' => "Answer $i", + ]); + $answer->save(); + $answers[] = $answer; + } + + $question = Question::create([ + 'bundle' => 'matching_question', + 'label' => 'Matching Question', + 'description' => 'Matching Question', + 'question' => 'Matching Question?', + 'response_type' => 'matching_response', + 'max_score' => 100, + 'answers' => $answers, + ]); + + $question->save(); + + return $question; + } + + /** + * Get direct question with answer. + */ + public function getDirectQuestionWithAnswers(): Question { + $answers = []; + + for ($i = 1; $i <= 5; $i++) { + $answer = QuestionAnswer::create([ + 'bundle' => 'direct_answer', + 'label' => "Answer $i", + 'answer' => "Answer $i", + ]); + $answer->save(); + $answers[] = $answer; + } + + $question = Question::create([ + 'bundle' => 'direct_question', + 'label' => 'Direct Question', + 'description' => 'Direct Question', + 'question' => 'Direct Question?', + 'response_type' => 'direct_response', + 'max_score' => 100, + 'answers' => $answers, + ]); + + $question->save(); + + return $question; + } + + /** + * Get boolean question with answer. + */ + public function getBooleanQuestionWithAnswers(): Question { + $question = Question::create([ + 'bundle' => 'boolean_question', + 'label' => 'Boolean Question', + 'description' => 'Boolean Question', + 'question' => 'Boolean Question?', + 'response_type' => 'boolean_response', + 'max_score' => 100, + ]); + + $question->save(); + + return $question; + } + + /** + * Get quiz. + */ + public function getQuiz(): Quiz { + $quiz = Quiz::create([ + 'bundle' => 'standard', + 'label' => 'Empty quiz', + 'description' => 'Empty quiz', + 'result_type' => 'standard', + 'attempts' => 5, + ]); + + $quiz->set('questions', [ + $this->getDirectQuestionWithAnswers(), + $this->getBooleanQuestionWithAnswers(), + $this->getMatchingQuestionWithAnswers(), + $this->getMultipleChoiceQuestionWithAnswers(), + $this->getSingleChoiceQuestionWithAnswers(), + ]); + + $quiz->save(); + return $quiz; + } + +}