Commit 1f2e49e6 authored by Julian Pustkuchen's avatar Julian Pustkuchen
Browse files

Issue #3265152: Write tests for basic functionality

parent f5c6fab8
Loading
Loading
Loading
Loading
+203 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\friendlycaptcha\Functional;

use Drupal\Tests\BrowserTestBase;
use Drupal\Core\StringTranslation\StringTranslationTrait;

/**
 * Test basic functionality of friendlycaptcha module.
 *
 * @group friendlycaptcha
 *
 * @dependencies captcha
 */
class FriendlyCaptchaBasicTest extends BrowserTestBase {

  use StringTranslationTrait;

  /**
   * A normal user.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $normalUser;

  /**
   * An admin user.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $adminUser;

  /**
   * Modules to enable.
   *
   * @var array
   */
  public static $modules = ['friendlycaptcha', 'captcha'];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();
    module_load_include('inc', 'captcha');

    // Create a normal user.
    $permissions = [
      'access content',
    ];
    $this->normalUser = $this->drupalCreateUser($permissions);

    // Create an admin user.
    $permissions += [
      'administer CAPTCHA settings',
      'skip CAPTCHA',
      'administer permissions',
      'administer content types',
      'administer friendlycaptcha',
    ];
    $this->adminUser = $this->drupalCreateUser($permissions);
  }

  /**
   * Helper function to generate a random Site Key.
   *
   * @return string
   *   Generated 16 char random site key.
   */
  protected function generateSiteKey() {
    $site_key = $this->randomMachineName(16);
    return $site_key;
  }

  /**
   * Helper function to generate a random API Key.
   *
   * @return string
   *   Generated 60 char random api key.
   */
  protected function generateApiKey() {
    $api_key = $this->randomMachineName(60);
    return $api_key;
  }

  /**
   * Test access to the administration page.
   */
  public function testFriendlycaptchaSettingsAdminAccess() {
    $this->drupalLogin($this->adminUser);
    $this->drupalGet('admin/config/people/captcha/friendlycaptcha');
    $this->assertSession()->pageTextNotContains($this->t('Access denied'), 'Admin users should be able to access the Friendlycaptcha admin page', 'Friendlycaptcha');
    $this->drupalLogout();
  }

  /**
   * Test the Friendlycaptcha settings form.
   */
  public function testFriendlycaptchaAdminSettingsForm() {
    $this->drupalLogin($this->adminUser);

    $site_key = $this->generateSiteKey();
    $api_key = $this->generateApiKey();
    $endpoint = 'global';

    // Check form validation.
    $edit['friendlycaptcha_site_key'] = '';
    $edit['friendlycaptcha_api_key'] = '';
    $this->drupalPostForm('admin/config/people/captcha/friendlycaptcha', $edit, $this->t('Save configuration'));

    $this->assertSession()->responseContains($this->t('Site key field is required.'), '[testFriendlycaptchaAdminSettingsForm]: Empty site key detected.');
    $this->assertSession()->responseContains($this->t('API key field is required.'), '[testFriendlycaptchaAdminSettingsForm]: Empty api key detected.');

    // Save form with valid values.
    $edit['friendlycaptcha_site_key'] = $site_key;
    $edit['friendlycaptcha_api_key'] = $api_key;
    $edit['friendlycaptcha_api_endpoint'] = $endpoint;
    $this->drupalPostForm('admin/config/people/captcha/friendlycaptcha', $edit, $this->t('Save configuration'));
    $this->assertSession()->responseContains($this->t('The configuration options have been saved.'), '[testFriendlycaptchaAdminSettingsForm]: The configuration options have been saved.');

    $this->assertSession()->responseNotContains($this->t('Site key field is required.'), '[testFriendlycaptchaAdminSettingsForm]: Site key was not empty.');
    $this->assertSession()->responseNotContains($this->t('Secret key field is required.'), '[testFriendlycaptchaAdminSettingsForm]: Secret key was not empty.');
    $this->assertSession()->responseNotContains($this->t('The tabindex must be an integer.'), '[testFriendlycaptchaAdminSettingsForm]: Tab index had a valid input.');

    $this->drupalLogout();
  }

  /**
   * Testing the protection of the user login form.
   */
  public function testFriendlycaptchaOnLoginForm() {
    $site_key = $this->generateSiteKey();
    $api_key = $this->generateApiKey();

    $friendlyCaptchaHtml = '<div class="frc-captcha" data-sitekey="' . $site_key . '" data-lang="en">';
    $friendlyCaptchaNoScriptHtml = '<noscript>' . t('You need Javascript for CAPTCHA verification to submit this form.') . '</noscript>';

    // Test if login works.
    $this->drupalLogin($this->normalUser);
    $this->drupalLogout();

    $this->drupalGet('user/login');
    $this->assertSession()->responseNotContains($friendlyCaptchaHtml, '[testFriendlycaptchaOnLoginForm]: Friendlycaptcha is not shown on form.');
    $this->assertSession()->responseNotContains($friendlyCaptchaNoScriptHtml, '[testFriendlycaptchaOnLoginForm]: Friendlycaptcha NoScript is not shown on form.');

    // Enable 'captcha/Math' CAPTCHA on login form.
    captcha_set_form_id_setting('user_login_form', 'captcha/Math');

    $this->drupalGet('user/login');
    $this->assertSession()->responseNotContains($friendlyCaptchaHtml, '[testFriendlycaptchaOnLoginForm]: Friendlycaptcha is not shown on form.');
    $this->assertSession()->responseNotContains($friendlyCaptchaNoScriptHtml, '[testFriendlycaptchaOnLoginForm]: Friendlycaptcha NoScript is not shown on form.');

    // Enable 'friendlycaptcha/friendlycaptcha' on login form.
    captcha_set_form_id_setting('user_login_form', 'friendlycaptcha/friendlycaptcha');
    $result = captcha_get_form_id_setting('user_login_form');
    $this->assertNotNull($result, 'A configuration has been found for CAPTCHA point: user_login_form', 'Friendlycaptcha');
    $this->assertEquals($result->getCaptchaType(), 'friendlycaptcha/friendlycaptcha', 'Friendlycaptcha type has been configured for CAPTCHA point: user_login_form');

    // Check if a Math CAPTCHA is still shown on the login form. The site key
    // and security key have not yet configured for Friendlycaptcha.
    // The module needs to fall back to math captcha.
    $this->drupalGet('user/login');
    $this->assertSession()->responseContains($this->t('Math question'), '[testFriendlycaptchaOnLoginForm]: Math CAPTCHA is shown on form.');

    // Configure site key and security key to show Friendlycaptcha
    // and no fall back.
    $this->config('friendlycaptcha.settings')
      ->set('site_key', $site_key)
      ->set('api_key', $api_key)
      ->save();

    // Check if there is a Friendlycaptcha on the login form.
    $this->drupalGet('user/login');
    $this->assertSession()->responseContains($friendlyCaptchaHtml, '[testFriendlycaptchaOnLoginForm]: Friendlycaptcha is shown on form.');
    $this->assertSession()->responseContains('friendly-challenge/widget.min.js', '[testFriendlycaptchaOnLoginForm]: Friendlycaptcha widget JS is present.');
    $this->assertSession()->responseContains($friendlyCaptchaNoScriptHtml, '[testFriendlycaptchaOnLoginForm]: Friendlycaptcha NoScript is shown on form.');

    // @todo Check that the widget is not only present, but also loaded!
    // Try to log in, which should fail.
    $edit['name'] = $this->normalUser->getAccountName();
    $edit['pass'] = $this->normalUser->getPassword();
    $this->assertSession()->responseContains('captcha_response');
    $this->assertSession()
      ->hiddenFieldExists('captcha_response')
      ->setValue('?');

    $this->drupalPostForm('user/login', $edit, $this->t('Log in'));
    // Check for error message.
    $this->assertSession()->pageTextContains($this->t('The answer you entered for the CAPTCHA was not correct.'), 'CAPTCHA should block user login form', 'Friendlycaptcha');

    // And make sure that user is not logged in: check for name and password
    // fields on "?q=user".
    $this->drupalGet('user/login');
    $this->assertSession()->fieldExists('name');
    $this->assertSession()->fieldExists('pass');
  }

}