DomainTestBase.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. namespace Drupal\Tests\domain\Functional;
  3. use Drupal\Core\Session\AccountInterface;
  4. use Drupal\Component\Utility\Crypt;
  5. use Drupal\Tests\BrowserTestBase;
  6. use Drupal\domain\DomainInterface;
  7. use Drupal\Tests\domain\Traits\DomainTestTrait;
  8. /**
  9. * Class DomainTestBase.
  10. *
  11. * @package Drupal\Tests\domain\Functional
  12. */
  13. abstract class DomainTestBase extends BrowserTestBase {
  14. use DomainTestTrait;
  15. /**
  16. * Sets a base hostname for running tests.
  17. *
  18. * When creating test domains, try to use $this->baseHostname or the
  19. * domainCreateTestDomains() method.
  20. *
  21. * @var string
  22. */
  23. public $baseHostname;
  24. /**
  25. * Modules to enable.
  26. *
  27. * @var array
  28. */
  29. public static $modules = ['domain', 'node'];
  30. /**
  31. * We use the standard profile for testing.
  32. *
  33. * @var string
  34. */
  35. protected $profile = 'standard';
  36. /**
  37. * {@inheritdoc}
  38. */
  39. protected function setUp() {
  40. parent::setUp();
  41. // Set the base hostname for domains.
  42. $this->baseHostname = \Drupal::entityTypeManager()->getStorage('domain')->createHostname();
  43. }
  44. /**
  45. * The methods below are brazenly copied from Rules module.
  46. *
  47. * They are all helper methods that make writing tests a bit easier.
  48. */
  49. /**
  50. * Finds link with specified locator.
  51. *
  52. * @param string $locator
  53. * Link id, title, text or image alt.
  54. *
  55. * @return \Behat\Mink\Element\NodeElement|null
  56. * The link node element.
  57. */
  58. public function findLink($locator) {
  59. return $this->getSession()->getPage()->findLink($locator);
  60. }
  61. /**
  62. * Confirms absence of link with specified locator.
  63. *
  64. * @param string $locator
  65. * Link id, title, text or image alt.
  66. *
  67. * @return bool
  68. * TRUE if link is absent, or FALSE.
  69. */
  70. public function findNoLink($locator) {
  71. return empty($this->getSession()->getPage()->hasLink($locator));
  72. }
  73. /**
  74. * Finds field (input, textarea, select) with specified locator.
  75. *
  76. * @param string $locator
  77. * Input id, name or label.
  78. *
  79. * @return \Behat\Mink\Element\NodeElement|null
  80. * The input field element.
  81. */
  82. public function findField($locator) {
  83. return $this->getSession()->getPage()->findField($locator);
  84. }
  85. /**
  86. * Finds button with specified locator.
  87. *
  88. * @param string $locator
  89. * Button id, value or alt.
  90. *
  91. * @return \Behat\Mink\Element\NodeElement|null
  92. * The button node element.
  93. */
  94. public function findButton($locator) {
  95. return $this->getSession()->getPage()->findButton($locator);
  96. }
  97. /**
  98. * Presses button with specified locator.
  99. *
  100. * @param string $locator
  101. * Button id, value or alt.
  102. *
  103. * @throws \Behat\Mink\Exception\ElementNotFoundException
  104. */
  105. public function pressButton($locator) {
  106. $this->getSession()->getPage()->pressButton($locator);
  107. }
  108. /**
  109. * Fills in field (input, textarea, select) with specified locator.
  110. *
  111. * @param string $locator
  112. * Input id, name or label.
  113. * @param string $value
  114. * Value.
  115. *
  116. * @throws \Behat\Mink\Exception\ElementNotFoundException
  117. *
  118. * @see \Behat\Mink\Element\NodeElement::setValue
  119. */
  120. public function fillField($locator, $value) {
  121. $this->getSession()->getPage()->fillField($locator, $value);
  122. }
  123. /**
  124. * Checks checkbox with specified locator.
  125. *
  126. * @param string $locator
  127. * An input id, name or label.
  128. *
  129. * @throws \Behat\Mink\Exception\ElementNotFoundException
  130. */
  131. public function checkField($locator) {
  132. $this->getSession()->getPage()->checkField($locator);
  133. }
  134. /**
  135. * Unchecks checkbox with specified locator.
  136. *
  137. * @param string $locator
  138. * An input id, name or label.
  139. *
  140. * @throws \Behat\Mink\Exception\ElementNotFoundException
  141. */
  142. public function uncheckField($locator) {
  143. $this->getSession()->getPage()->uncheckField($locator);
  144. }
  145. /**
  146. * Selects option from select field with specified locator.
  147. *
  148. * @param string $locator
  149. * An input id, name or label.
  150. * @param string $value
  151. * The option value.
  152. * @param bool $multiple
  153. * Whether to select multiple options.
  154. *
  155. * @throws \Behat\Mink\Exception\ElementNotFoundException
  156. *
  157. * @see NodeElement::selectOption
  158. */
  159. public function selectFieldOption($locator, $value, $multiple = FALSE) {
  160. $this->getSession()->getPage()->selectFieldOption($locator, $value, $multiple);
  161. }
  162. /**
  163. * Returns whether a given user account is logged in.
  164. *
  165. * @param \Drupal\Core\Session\AccountInterface $account
  166. * The user account object to check.
  167. *
  168. * @return bool
  169. * TRUE if a given user account is logged in, or FALSE.
  170. */
  171. protected function drupalUserIsLoggedIn(AccountInterface $account) {
  172. // @TODO: This is a temporary hack for the test login fails when setting $cookie_domain.
  173. if (!isset($account->session_id)) {
  174. return (bool) $account->id();
  175. }
  176. // The session ID is hashed before being stored in the database.
  177. // @see \Drupal\Core\Session\SessionHandler::read()
  178. return (bool) db_query("SELECT sid FROM {users_field_data} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid", [':sid' => Crypt::hashBase64($account->session_id)])->fetchField();
  179. }
  180. /**
  181. * Login a user on a specific domain.
  182. *
  183. * @param \Drupal\domain\DomainInterface $domain
  184. * The domain to log the user into.
  185. * @param \Drupal\Core\Session\AccountInterface $account
  186. * The user account to login.
  187. */
  188. public function domainLogin(DomainInterface $domain, AccountInterface $account) {
  189. // Due to a quirk in session handling that we cannot directly access, it
  190. // works if we login, then logout, and then login to a specific domain.
  191. $this->drupalLogin($account);
  192. if ($this->loggedInUser) {
  193. $this->drupalLogout();
  194. }
  195. // Login.
  196. $url = $domain->getPath() . 'user/login';
  197. $this->submitForm([
  198. 'name' => $account->getUsername(),
  199. 'pass' => $account->passRaw,
  200. ], t('Log in'));
  201. // @see BrowserTestBase::drupalUserIsLoggedIn()
  202. $account->sessionId = $this->getSession()->getCookie($this->getSessionName());
  203. $this->assertTrue($this->drupalUserIsLoggedIn($account), 'User successfully logged in.');
  204. $this->loggedInUser = $account;
  205. $this->container->get('current_user')->setAccount($account);
  206. }
  207. }