quiz-6.0.0-alpha4/modules/quiz_multichoice/tests/src/Functional/QuizMultichoiceTestCase.php

modules/quiz_multichoice/tests/src/Functional/QuizMultichoiceTestCase.php
<?php

namespace Drupal\Tests\quiz_multichoice\Functional;

use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\paragraphs\Entity\Paragraph;
use Drupal\quiz\Entity\QuizQuestion;
use Drupal\quiz\Entity\QuizResult;
use Drupal\Tests\quiz\Functional\QuizQuestionTestBase;

/**
 * Test multiple choice questions.
 *
 * @group Quiz
 */
class QuizMultichoiceTestCase extends QuizQuestionTestBase {

  use StringTranslationTrait;

  /**
   * Modules to install.
   *
   * @var array
   */
  protected static $modules = ['quiz', 'quiz_multichoice'];

  /**
   * Create a default MCQ with default settings.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  private function testCreateQuizQuestion($settings = []) {

    // Set up some alternatives.
    $a = Paragraph::create([
      'type' => 'multichoice',
      'multichoice_correct' => 1,
      'multichoice_answer' => 'Alternative A',
      'multichoice_feedback_chosen' => 'You chose A',
      'multichoice_feedback_not_chosen' => 'You did not choose A',
      'multichoice_score_chosen' => 1,
      'multichoice_score_not_chosen' => 0,
    ]);
    $a->save();

    $b = Paragraph::create([
      'type' => 'multichoice',
      'multichoice_answer' => 'Alternative B',
      'multichoice_feedback_chosen' => 'You chose B',
      'multichoice_feedback_not_chosen' => 'You did not choose B',
      'multichoice_score_chosen' => -1,
      'multichoice_score_not_chosen' => 0,
    ]);
    $b->save();

    $c = Paragraph::create([
      'type' => 'multichoice',
      'multichoice_answer' => 'Alternative C',
      'multichoice_feedback_chosen' => 'You chose C',
      'multichoice_feedback_not_chosen' => 'You did not choose C',
      'multichoice_score_chosen' => -1,
      'multichoice_score_not_chosen' => 0,
    ]);
    $c->save();

    $question = QuizQuestion::create($settings + [
      'title' => 'MCQ 1 Title',
      'type' => 'multichoice',
      'choice_multi' => 0,
      'choice_random' => 0,
      'choice_boolean' => 0,
      'body' => 'MCQ 1 body text',
    ]);

    $question->get('alternatives')->appendItem($a);
    $question->get('alternatives')->appendItem($b);
    $question->get('alternatives')->appendItem($c);

    $question->save();

    return $question;
  }

  /**
   * Test question feedback.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   * @throws \Behat\Mink\Exception\ExpectationException
   */
  public function testQuestionFeedback() {
    $this->drupalLogin($this->admin);

    $question = $this->testCreateQuizQuestion();
    $quiz = $this->linkQuestionToQuiz($question);

    // Login as non-admin.
    $this->drupalLogin($this->user);

    // Test incorrect question. Feedback, answer.
    $this->drupalGet("quiz/{$quiz->id()}/take");
    $this->submitForm([
      "question[{$question->id()}][answer][user_answer]" => 2,
    ], $this->t('Finish'));
    $this->assertSession()->responseMatches('/quiz-score-icon selected/');
    $this->assertSession()->responseMatches('/quiz-score-icon should/');
    $this->assertSession()->responseMatches('/quiz-score-icon incorrect/');
    $this->assertSession()->pageTextContains('You did not choose A');
    $this->assertSession()->pageTextContains('You chose B');
    $this->assertSession()->pageTextContains('You did not choose C');
  }

  /**
   * Test multiple answers.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   * @throws \Behat\Mink\Exception\ResponseTextException
   */
  public function testMultipleAnswers() {
    $this->drupalLogin($this->admin);
    $question = $this->testCreateQuizQuestion(['choice_multi' => 1]);
    $quiz = $this->linkQuestionToQuiz($question);

    $this->drupalLogin($this->user);
    $this->drupalGet("quiz/{$quiz->id()}/take");
    $this->submitForm([
      "question[{$question->id()}][answer][user_answer][1]" => 1,
      "question[{$question->id()}][answer][user_answer][3]" => 3,
    ], $this->t('Finish'));
    // 0 of 1, because user picked a correct answer and an incorrect answer.
    $this->assertSession()->pageTextContains('You got 0 of 1 possible points.');
    $this->assertSession()->pageTextContains('Your score: 0%');

    $this->drupalGet("quiz/{$quiz->id()}/take");
    $this->submitForm([
      "question[{$question->id()}][answer][user_answer][1]" => 1,
    ], $this->t('Finish'));
    // 1 of 1, because user picked a correct answer and not an incorrect answer.
    $this->assertSession()->pageTextContains('You got 1 of 1 possible points.');
    $this->assertSession()->pageTextContains('Your score: 100%');
  }

  /**
   * Test restoring a multiple choice answer.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   * @throws \Behat\Mink\Exception\ExpectationException
   */
  public function testAnswerMultiRestore() {
    // Checkboxes.
    $this->drupalLogin($this->admin);
    $question = $this->testCreateQuizQuestion(['choice_multi' => 1]);
    $question2 = $this->testCreateQuizQuestion(['choice_multi' => 1]);
    $quiz = $this->linkQuestionToQuiz($question);
    $this->linkQuestionToQuiz($question2, $quiz);

    $this->drupalLogin($this->user);
    $this->drupalGet("quiz/{$quiz->id()}/take");
    $this->submitForm([
      "question[{$question->id()}][answer][user_answer][1]" => 1,
    ], $this->t('Next'));
    $this->drupalGet("quiz/{$quiz->id()}/take/1");
    $this->assertSession()->checkboxChecked('edit-question-1-answer-user-answer-1');
  }

  /**
   * Test restoring a single choice answer.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   * @throws \Behat\Mink\Exception\ExpectationException
   */
  public function testAnswerSingleRestore() {
    // Radio buttons.
    $this->drupalLogin($this->admin);
    $question = $this->testCreateQuizQuestion(['choice_multi' => 0]);
    $question2 = $this->testCreateQuizQuestion(['choice_multi' => 0]);
    $quiz = $this->linkQuestionToQuiz($question);
    $this->linkQuestionToQuiz($question2, $quiz);

    $this->drupalLogin($this->user);
    $this->drupalGet("quiz/{$quiz->id()}/take");
    $this->submitForm([
      "question[{$question->id()}][answer][user_answer]" => 1,
    ], $this->t('Next'));
    $this->drupalGet("quiz/{$quiz->id()}/take/1");
    $this->assertSession()->checkboxChecked('edit-question-1-answer-user-answer-1');
  }

  /**
   * Test random order of choices.
   *
   * @todo I don't know how we would test random questions.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function testRandomOrder() {
    $this->drupalLogin($this->admin);
    $question = $this->testCreateQuizQuestion(['choice_random' => 1]);
    $quiz = $this->linkQuestionToQuiz($question);

    $this->drupalLogin($this->user);

    $this->drupalGet("quiz/{$quiz->id()}/take");
    $this->submitForm([
      "question[{$question->id()}][answer][user_answer]" => 1,
    ], $this->t('Finish'));
  }

  /**
   * Test simple scoring.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   * @throws \Behat\Mink\Exception\ResponseTextException
   */
  public function testSimpleScoring() {
    $this->drupalLogin($this->admin);

    // Set up some alternatives. Two of the answers are correct.
    $a = Paragraph::create([
      'type' => 'multichoice',
      'multichoice_correct' => 1,
      'multichoice_answer' => 'Alternative A',
      'multichoice_score_chosen' => 1,
      'multichoice_score_not_chosen' => 0,
    ]);
    $a->save();

    $b = Paragraph::create([
      'type' => 'multichoice',
      'multichoice_correct' => 1,
      'multichoice_answer' => 'Alternative B',
      'multichoice_score_chosen' => 1,
      'multichoice_score_not_chosen' => 0,
    ]);
    $b->save();

    $c = Paragraph::create([
      'type' => 'multichoice',
      'multichoice_correct' => 0,
      'multichoice_answer' => 'Alternative C',
      'multichoice_score_chosen' => 0,
      'multichoice_score_not_chosen' => 0,
    ]);
    $c->save();

    // Set simple scoring so choosing both answers is required.
    $question = QuizQuestion::create([
      'title' => 'MCQ 1 Title',
      'type' => 'multichoice',
      'choice_multi' => 1,
      'choice_random' => 0,
      'choice_boolean' => 1,
      'body' => 'MCQ 1 body text',
    ]);

    $question->get('alternatives')->appendItem($a);
    $question->get('alternatives')->appendItem($b);
    $question->get('alternatives')->appendItem($c);

    $question->save();

    $quiz = $this->linkQuestionToQuiz($question);

    $this->drupalLogin($this->user);

    // Test selecting a wrong answer, incorrect.
    $this->drupalGet("quiz/{$quiz->id()}/take");
    $this->submitForm([
      "question[{$question->id()}][answer][user_answer][1]" => 1,
      "question[{$question->id()}][answer][user_answer][3]" => 3,
    ], $this->t('Finish'));
    $this->assertSession()->pageTextContains('You got 0 of 1 possible points.');
    $this->assertSession()->pageTextContains('Your score: 0%');
    // Get the last result and make sure it is 0%.
    $efq = \Drupal::entityQuery('quiz_result');
    $result = $efq->range(0, 1)
      ->accessCheck(FALSE)
      ->condition('qid', $quiz->id())
      ->condition('uid', $this->user->id())
      ->sort('result_id', 'desc')
      ->execute();
    $keys = array_keys($result);
    $existing = QuizResult::load(reset($keys));
    $this->assertEquals(0, $existing->get('score')->value, 'Score is 0%');

    // Test selecting all answers, which would be incorrect.
    $this->drupalGet("quiz/{$quiz->id()}/take");
    $this->submitForm([
      "question[{$question->id()}][answer][user_answer][1]" => 1,
      "question[{$question->id()}][answer][user_answer][2]" => 1,
      "question[{$question->id()}][answer][user_answer][3]" => 1,
    ], $this->t('Finish'));
    $this->assertSession()->pageTextContains('You got 0 of 1 possible points.');
    $this->assertSession()->pageTextContains('Your score: 0%');
    // Get the last result and make sure it is 0%.
    $efq = \Drupal::entityQuery('quiz_result');
    $result = $efq->range(0, 1)
      ->accessCheck(FALSE)
      ->condition('qid', $quiz->id())
      ->condition('uid', $this->user->id())
      ->sort('result_id', 'desc')
      ->execute();
    $keys = array_keys($result);
    $existing = QuizResult::load(reset($keys));
    $this->assertEquals(0, $existing->get('score')->value, 'Score is 0%');

    // Correct.
    $this->drupalGet("quiz/{$quiz->id()}/take");
    $this->submitForm([
      "question[{$question->id()}][answer][user_answer][1]" => 1,
      "question[{$question->id()}][answer][user_answer][2]" => 1,
    ], $this->t('Finish'));
    $this->assertSession()->pageTextContains('You got 1 of 1 possible points.');
    $this->assertSession()->pageTextContains('Your score: 100%');

    // Get the last result and make sure it is 100%, not 200%.
    $efq = \Drupal::entityQuery('quiz_result');
    $result = $efq->range(0, 1)
      ->accessCheck(FALSE)
      ->condition('qid', $quiz->id())
      ->condition('uid', $this->user->id())
      ->sort('result_id', 'desc')
      ->execute();
    $keys = array_keys($result);
    $existing = QuizResult::load(reset($keys));
    $this->assertEquals(100, $existing->get('score')->value, 'Score is 100%');
  }

  /**
   * Test that the question response can be edited.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function testEditQuestionResponse() {
    // Create & link a question.
    $question = $this->testCreateQuizQuestion();
    $quiz = $this->linkQuestionToQuiz($question);

    $question2 = $this->testCreateQuizQuestion();
    $this->linkQuestionToQuiz($question2, $quiz);

    // Login as non-admin.
    $this->drupalLogin($this->user);

    // Take the quiz.
    $this->drupalGet("quiz/{$quiz->id()}/take");

    // Test editing a question.
    $this->drupalGet("quiz/{$quiz->id()}/take");
    $this->drupalGet("quiz/{$quiz->id()}/take/1");
    $this->submitForm([
      "question[{$question->id()}][answer][user_answer]" => 1,
    ], $this->t('Next'));
    $this->drupalGet("quiz/{$quiz->id()}/take/1");
    $this->submitForm([
      "question[{$question->id()}][answer][user_answer]" => 2,
    ], $this->t('Next'));
  }

  /**
   * {@inheritdoc}
   */
  public function getQuestionType(): string {
    return 'multichoice';
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc