EmailAddressTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Validate
  17. * @subpackage UnitTests
  18. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. /**
  23. * Test helper
  24. */
  25. require_once dirname(__FILE__) . '/../../TestHelper.php';
  26. /**
  27. * @see Zend_Validate_EmailAddress
  28. */
  29. require_once 'Zend/Validate/EmailAddress.php';
  30. /**
  31. * @category Zend
  32. * @package Zend_Validate
  33. * @subpackage UnitTests
  34. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  35. * @license http://framework.zend.com/license/new-bsd New BSD License
  36. */
  37. class Zend_Validate_EmailAddressTest extends PHPUnit_Framework_TestCase
  38. {
  39. /**
  40. * Default instance created for all test methods
  41. *
  42. * @var Zend_Validate_EmailAddress
  43. */
  44. protected $_validator;
  45. /**
  46. * Creates a new Zend_Validate_EmailAddress object for each test method
  47. *
  48. * @return void
  49. */
  50. public function setUp()
  51. {
  52. $this->_validator = new Zend_Validate_EmailAddress();
  53. }
  54. /**
  55. * Ensures that a basic valid e-mail address passes validation
  56. *
  57. * @return void
  58. */
  59. public function testBasic()
  60. {
  61. $this->assertTrue($this->_validator->isValid('username@example.com'));
  62. }
  63. /**
  64. * Ensures that localhost address is valid
  65. *
  66. * @return void
  67. */
  68. public function testLocalhostAllowed()
  69. {
  70. $validator = new Zend_Validate_EmailAddress(Zend_Validate_Hostname::ALLOW_ALL);
  71. $this->assertTrue($validator->isValid('username@localhost'));
  72. }
  73. /**
  74. * Ensures that local domain names are valid
  75. *
  76. * @return void
  77. */
  78. public function testLocaldomainAllowed()
  79. {
  80. $validator = new Zend_Validate_EmailAddress(Zend_Validate_Hostname::ALLOW_ALL);
  81. $this->assertTrue($validator->isValid('username@localhost.localdomain'));
  82. }
  83. /**
  84. * Ensures that IP hostnames are valid
  85. *
  86. * @return void
  87. */
  88. public function testIPAllowed()
  89. {
  90. $validator = new Zend_Validate_EmailAddress(Zend_Validate_Hostname::ALLOW_DNS | Zend_Validate_Hostname::ALLOW_IP);
  91. $valuesExpected = array(
  92. array(Zend_Validate_Hostname::ALLOW_DNS, true, array('bob@212.212.20.4')),
  93. array(Zend_Validate_Hostname::ALLOW_DNS, false, array('bob@localhost'))
  94. );
  95. foreach ($valuesExpected as $element) {
  96. foreach ($element[2] as $input) {
  97. $this->assertEquals($element[1], $validator->isValid($input), implode("\n", $validator->getMessages()));
  98. }
  99. }
  100. }
  101. /**
  102. * Ensures that validation fails when the local part is missing
  103. *
  104. * @return void
  105. */
  106. public function testLocalPartMissing()
  107. {
  108. $this->assertFalse($this->_validator->isValid('@example.com'));
  109. $messages = $this->_validator->getMessages();
  110. $this->assertEquals(1, count($messages));
  111. $this->assertContains('local-part@hostname', current($messages));
  112. }
  113. /**
  114. * Ensures that validation fails and produces the expected messages when the local part is invalid
  115. *
  116. * @return void
  117. */
  118. public function testLocalPartInvalid()
  119. {
  120. $this->assertFalse($this->_validator->isValid('Some User@example.com'));
  121. $messages = $this->_validator->getMessages();
  122. $this->assertEquals(3, count($messages));
  123. $this->assertContains('Some User', current($messages));
  124. $this->assertContains('dot-atom', current($messages));
  125. $this->assertContains('Some User', next($messages));
  126. $this->assertContains('quoted-string', current($messages));
  127. $this->assertContains('Some User', next($messages));
  128. $this->assertContains('not a valid local part', current($messages));
  129. }
  130. /**
  131. * Ensures that no validation failure message is produced when the local part follows the quoted-string format
  132. *
  133. * @return void
  134. */
  135. public function testLocalPartQuotedString()
  136. {
  137. $this->assertTrue($this->_validator->isValid('"Some User"@example.com'));
  138. $messages = $this->_validator->getMessages();
  139. $this->assertType('array', $messages);
  140. $this->assertEquals(0, count($messages));
  141. }
  142. /**
  143. * Ensures that validation fails when the hostname is invalid
  144. *
  145. * @return void
  146. */
  147. public function testHostnameInvalid()
  148. {
  149. $this->assertFalse($this->_validator->isValid('username@ example . com'));
  150. $messages = $this->_validator->getMessages();
  151. $this->assertThat(count($messages), $this->greaterThanOrEqual(1));
  152. $this->assertContains('not a valid hostname', current($messages));
  153. }
  154. /**
  155. * Ensures that quoted-string local part is considered valid
  156. *
  157. * @return void
  158. */
  159. public function testQuotedString()
  160. {
  161. $emailAddresses = array(
  162. '"username"@example.com',
  163. '"bob%jones"@domain.com',
  164. '"bob jones"@domain.com',
  165. '"bob@jones"@domain.com',
  166. '"[[ bob ]]"@domain.com',
  167. '"jones"@domain.com'
  168. );
  169. foreach ($emailAddresses as $input) {
  170. $this->assertTrue($this->_validator->isValid($input), "$input failed to pass validation:\n"
  171. . implode("\n", $this->_validator->getMessages()));
  172. }
  173. }
  174. /**
  175. * Ensures that validation fails when the e-mail is given as for display,
  176. * with angle brackets around the actual address
  177. *
  178. * @return void
  179. */
  180. public function testEmailDisplay()
  181. {
  182. $this->assertFalse($this->_validator->isValid('User Name <username@example.com>'));
  183. $messages = $this->_validator->getMessages();
  184. $this->assertThat(count($messages), $this->greaterThanOrEqual(3));
  185. $this->assertContains('not a valid hostname', current($messages));
  186. $this->assertContains('cannot match TLD', next($messages));
  187. $this->assertContains('does not appear to be a valid local network name', next($messages));
  188. }
  189. /**
  190. * Ensures that the validator follows expected behavior for valid email addresses
  191. *
  192. * @return void
  193. */
  194. public function testBasicValid()
  195. {
  196. $emailAddresses = array(
  197. 'bob@domain.com',
  198. 'bob.jones@domain.co.uk',
  199. 'bob.jones.smythe@domain.co.uk',
  200. 'BoB@domain.museum',
  201. 'bobjones@domain.info',
  202. "B.O'Callaghan@domain.com",
  203. 'bob+jones@domain.us',
  204. 'bob+jones@domain.co.uk',
  205. 'bob@some.domain.uk.com',
  206. 'bob@verylongdomainsupercalifragilisticexpialidociousspoonfulofsugar.com'
  207. );
  208. foreach ($emailAddresses as $input) {
  209. $this->assertTrue($this->_validator->isValid($input), "$input failed to pass validation:\n"
  210. . implode("\n", $this->_validator->getMessages()));
  211. }
  212. }
  213. /**
  214. * Ensures that the validator follows expected behavior for invalid email addresses
  215. *
  216. * @return void
  217. */
  218. public function testBasicInvalid()
  219. {
  220. $emailAddresses = array(
  221. '',
  222. 'bob
  223. @domain.com',
  224. 'bob jones@domain.com',
  225. '.bobJones@studio24.com',
  226. 'bobJones.@studio24.com',
  227. 'bob.Jones.@studio24.com',
  228. '"bob%jones@domain.com',
  229. 'bob@verylongdomainsupercalifragilisticexpialidociousaspoonfulofsugar.com',
  230. 'bob+domain.com',
  231. 'bob.domain.com',
  232. 'bob @domain.com',
  233. 'bob@ domain.com',
  234. 'bob @ domain.com',
  235. 'Abc..123@example.com'
  236. );
  237. foreach ($emailAddresses as $input) {
  238. $this->assertFalse($this->_validator->isValid($input), implode("\n", $this->_validator->getMessages()) . $input);
  239. }
  240. }
  241. /**
  242. * Ensures that the validator follows expected behavior for valid email addresses with complex local parts
  243. *
  244. * @return void
  245. */
  246. public function testComplexLocalValid()
  247. {
  248. $emailAddresses = array(
  249. 'Bob.Jones@domain.com',
  250. 'Bob.Jones!@domain.com',
  251. 'Bob&Jones@domain.com',
  252. '/Bob.Jones@domain.com',
  253. '#Bob.Jones@domain.com',
  254. 'Bob.Jones?@domain.com',
  255. 'Bob~Jones@domain.com'
  256. );
  257. foreach ($emailAddresses as $input) {
  258. $this->assertTrue($this->_validator->isValid($input));
  259. }
  260. }
  261. /**
  262. * Ensures that the validator follows expected behavior for checking MX records
  263. *
  264. * @return void
  265. */
  266. public function testMXRecords()
  267. {
  268. $validator = new Zend_Validate_EmailAddress(Zend_Validate_Hostname::ALLOW_DNS, true);
  269. // Are MX checks supported by this system?
  270. if (!$validator->validateMxSupported()) {
  271. return true;
  272. }
  273. $valuesExpected = array(
  274. array(true, array('Bob.Jones@zend.com', 'Bob.Jones@studio24.net')),
  275. array(false, array('Bob.Jones@madeupdomain242424a.com', 'Bob.Jones@madeupdomain242424b.net'))
  276. );
  277. foreach ($valuesExpected as $element) {
  278. foreach ($element[1] as $input) {
  279. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()));
  280. }
  281. }
  282. // Try a check via setting the option via a method
  283. unset($validator);
  284. $validator = new Zend_Validate_EmailAddress();
  285. $validator->setValidateMx(true);
  286. foreach ($valuesExpected as $element) {
  287. foreach ($element[1] as $input) {
  288. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()));
  289. }
  290. }
  291. }
  292. /**
  293. * Test changing hostname settings via EmailAddress object
  294. *
  295. * @return void
  296. */
  297. public function testHostnameSettings()
  298. {
  299. $validator = new Zend_Validate_EmailAddress();
  300. // Check no IDN matching
  301. $validator->getHostnameValidator()->setValidateIdn(false);
  302. $valuesExpected = array(
  303. array(false, array('name@b�rger.de', 'name@h�llo.de', 'name@h�llo.se'))
  304. );
  305. foreach ($valuesExpected as $element) {
  306. foreach ($element[1] as $input) {
  307. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()));
  308. }
  309. }
  310. // Check no TLD matching
  311. $validator->getHostnameValidator()->setValidateTld(false);
  312. $valuesExpected = array(
  313. array(true, array('name@domain.xx', 'name@domain.zz', 'name@domain.madeup'))
  314. );
  315. foreach ($valuesExpected as $element) {
  316. foreach ($element[1] as $input) {
  317. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()));
  318. }
  319. }
  320. }
  321. /**
  322. * Ensures that getMessages() returns expected default value (an empty array)
  323. *
  324. * @return void
  325. */
  326. public function testGetMessages()
  327. {
  328. $this->assertEquals(array(), $this->_validator->getMessages());
  329. }
  330. /**
  331. * @see ZF-2861
  332. */
  333. public function testHostnameValidatorMessagesShouldBeTranslated()
  334. {
  335. require_once 'Zend/Validate/Hostname.php';
  336. $hostnameValidator = new Zend_Validate_Hostname();
  337. require_once 'Zend/Translate.php';
  338. $translations = array(
  339. 'hostnameIpAddressNotAllowed' => 'hostnameIpAddressNotAllowed translation',
  340. 'hostnameUnknownTld' => 'hostnameUnknownTld translation',
  341. 'hostnameDashCharacter' => 'hostnameDashCharacter translation',
  342. 'hostnameInvalidHostnameSchema' => 'hostnameInvalidHostnameSchema translation',
  343. 'hostnameUndecipherableTld' => 'hostnameUndecipherableTld translation',
  344. 'hostnameInvalidHostname' => 'hostnameInvalidHostname translation',
  345. 'hostnameInvalidLocalName' => 'hostnameInvalidLocalName translation',
  346. 'hostnameLocalNameNotAllowed' => 'hostnameLocalNameNotAllowed translation',
  347. );
  348. $translator = new Zend_Translate('array', $translations);
  349. $this->_validator->setTranslator($translator)->setHostnameValidator($hostnameValidator);
  350. $this->_validator->isValid('_XX.!!3xx@0.239,512.777');
  351. $messages = $hostnameValidator->getMessages();
  352. $found = false;
  353. foreach ($messages as $code => $message) {
  354. if (array_key_exists($code, $translations)) {
  355. $this->assertEquals($translations[$code], $message);
  356. $found = true;
  357. break;
  358. }
  359. }
  360. $this->assertTrue($found);
  361. }
  362. /**
  363. * @see ZF-4888
  364. */
  365. public function testEmailsExceedingLength()
  366. {
  367. $emailAddresses = array(
  368. 'thislocalpathoftheemailadressislongerthantheallowedsizeof64characters@domain.com',
  369. 'bob@verylongdomainsupercalifragilisticexpialidociousspoonfulofsugarverylongdomainsupercalifragilisticexpialidociousspoonfulofsugarverylongdomainsupercalifragilisticexpialidociousspoonfulofsugarverylongdomainsupercalifragilisticexpialidociousspoonfulofsugarexpialidociousspoonfulofsugar.com',
  370. );
  371. foreach ($emailAddresses as $input) {
  372. $this->assertFalse($this->_validator->isValid($input));
  373. }
  374. }
  375. }