summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn C Fiala2010-01-19 00:00:18 (GMT)
committer John C Fiala2010-01-19 00:00:18 (GMT)
commita153d418bfa53e4c6db004590fffe2ed8aa65abe (patch)
tree988e752328ce6196ab8f968ccaea70dfdf7de6b3
parentc2dc35da2453113abe98eedc030752de04f35ebf (diff)
task #438770 by jcfiala: Adding more tests to validate various urls.
bug report #660138 by chris_bbg888: Changing validation to include letters with umlouts.
-rw-r--r--link.module40
-rw-r--r--tests/link.validate.test115
2 files changed, 124 insertions, 31 deletions
diff --git a/link.module b/link.module
index 17fa97e..43ec3af 100644
--- a/link.module
+++ b/link.module
@@ -10,7 +10,23 @@ define('LINK_EXTERNAL', 'external');
define('LINK_INTERNAL', 'internal');
define('LINK_FRONT', 'front');
define('LINK_EMAIL', 'email');
+define('LINK_NEWS', 'news');
define('LINK_DOMAINS', 'aero|arpa|asia|biz|com|cat|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|mobi|local');
+// There are many other characters which are legal other than simply a-z - this includes them.
+define('LINK_ICHARS', (string) html_entity_decode(implode("", array(
+ "æ", // æ
+ "Æ", // Æ
+ "ø", // ø
+ "Ø", // Ø
+ "å", // å
+ "Å", // Å
+ "ä", // ä
+ "Ä", // Ä
+ "ö", // ö
+ "Ö", // Ö
+ "ü", // ü
+ "Ü", // Ü
+ )), ENT_QUOTES, 'UTF-8'));
define('LINK_TARGET_DEFAULT', 'default');
define('LINK_TARGET_NEW_WINDOW', '_blank');
@@ -382,7 +398,7 @@ function _link_sanitize(&$item, $delta, &$field, &$node) {
}
// Remove the rel=nofollow for internal links.
- if ($type != LINK_EXTERNAL && strpos($item['attributes']['rel'], 'nofollow') !== FALSE) {
+ if ($type != LINK_EXTERNAL && $type != LINK_NEWS && strpos($item['attributes']['rel'], 'nofollow') !== FALSE) {
$item['attributes']['rel'] = str_replace('nofollow', '', $item['attributes']);
}
@@ -690,12 +706,11 @@ function link_cleanup_url($url, $protocol = "http") {
* the following attributes: protocol, hostname, ip, and port.
*/
function link_validate_url($text) {
-
$allowed_protocols = variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal'));
$protocol = '(('. implode("|", $allowed_protocols) .'):\/\/)';
- $authentication = '([a-z0-9]+(:[a-z0-9]+)?@)';
- $domain = '(([a-z0-9]([a-z0-9\-_\[\]])*)(\.(([a-z0-9\-_\[\]])+\.)*('. LINK_DOMAINS .'|[a-z]{2}))?)';
+ $authentication = '([a-z0-9' . LINK_ICHARS . ']+(:[a-z0-9'. LINK_ICHARS . ']+)?@)';
+ $domain = '(([a-z0-9' . LINK_ICHARS . ']([a-z0-9'. LINK_ICHARS . '\-_\[\]])*)(\.(([a-z0-9' . LINK_ICHARS . '\-_\[\]])+\.)*('. LINK_DOMAINS .'|[a-z]{2}))?)';
$ipv4 = '([0-9]{1,3}(\.[0-9]{1,3}){3})';
$ipv6 = '([0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7})';
$port = '(:([0-9]{1,5}))';
@@ -704,17 +719,21 @@ function link_validate_url($text) {
$external_pattern = '/^'. $protocol .'?'. $authentication .'?('. $domain .'|'. $ipv4 .'|'. $ipv6 .' |localhost)'. $port .'?';
// Pattern specific to internal links.
- $internal_pattern = "/^([a-z0-9_\-+\[\]]+)";
+ $internal_pattern = "/^([a-z0-9". LINK_ICHARS ."_\-+\[\]]+)";
- $directories = "(\/[a-z0-9_\-\.~+%=&,$'!():;*@\[\]]*)*";
+ $directories = "(\/[a-z0-9". LINK_ICHARS ."_\-\.~+%=&,$'!():;*@\[\]]*)*";
// Yes, four backslashes == a single backslash.
- $query = "(\/?\?([?a-z0-9+_|\-\.\/\\\\%=&,$'():;*@\[\]]*))";
- $anchor = "(#[a-z0-9_\-\.~+%=&,$'():;*@\[\]]*)";
+ $query = "(\/?\?([?a-z0-9". LINK_ICHARS ."+_|\-\.\/\\\\%=&,$'():;*@\[\]]*))";
+ $anchor = "(#[a-z0-9". LINK_ICHARS ."_\-\.~+%=&,$'():;*@\[\]]*)";
// The rest of the path for a standard URL.
$end = $directories .'?'. $query .'?'. $anchor .'?'.'$/i';
+
+ $message_id = '[^@].*@'. $domain;
+ $newsgroup_name = '([0-9a-z+-]*\.)*[0-9a-z+-]*';
+ $news_pattern = '/^news:('. $newsgroup_name .'|'. $message_id .')$/i';
- $user = '[a-zA-Z0-9_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\'\[\]]+';
+ $user = '[a-zA-Z0-9'. LINK_ICHARS .'_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\'\[\]]+';
$email_pattern = '/^mailto:'. $user .'@'.'('. $domain .'|'. $ipv4 .'|'. $ipv6 .'|localhost)'. $query .'?$/';
if (strpos($text, '<front>') === 0) {
@@ -723,6 +742,9 @@ function link_validate_url($text) {
if (in_array('mailto', $allowed_protocols) && preg_match($email_pattern, $text)) {
return LINK_EMAIL;
}
+ if (in_array('news', $allowed_protocols) && preg_match($news_pattern, $text)) {
+ return LINK_NEWS;
+ }
if (preg_match($internal_pattern . $end, $text)) {
return LINK_INTERNAL;
}
diff --git a/tests/link.validate.test b/tests/link.validate.test
index d464669..ef18ff4 100644
--- a/tests/link.validate.test
+++ b/tests/link.validate.test
@@ -9,9 +9,8 @@
// Let's include the parent class.
module_load_include('test', 'content', 'tests/content.crud');
-class LinkValidateTest extends ContentCrudTestCase {
-
- public $permissions = array(
+class LinkValidateTestCase extends ContentCrudTestCase {
+ public $permissions = array(
'access content',
'administer content types',
'administer nodes',
@@ -21,15 +20,7 @@ class LinkValidateTest extends ContentCrudTestCase {
'post comments without approval',
'access administration pages',
);
-
- function getInfo() {
- return array(
- 'name' => t('Link Validation Tests'),
- 'description' => t('Tests the field validation.'),
- 'group' => t('Link'),
- );
- }
-
+
function setUp() {
parent::setUp('link');
$this->loginWithPermissions($this->permissions);
@@ -43,7 +34,10 @@ class LinkValidateTest extends ContentCrudTestCase {
);
}
- function test_link_validate_basic_url() {
+ /**
+ * Takes a url, and sees if it can validate that the url is valid.
+ */
+ function link_test_validate_url($url) {
$this->acquireContentTypes(1);
variable_set('node_options_'. $this->content_types[0]->name, array('status', 'promote'));
$field_settings = array(
@@ -54,27 +48,44 @@ class LinkValidateTest extends ContentCrudTestCase {
);
$field = $this->createField($field_settings, 0);
- //$this->pass('<pre>'. print_r($field, TRUE) .'</pre>');
+
$field_db_info = content_database_info($field);
- $this->acquireNodes(2);
+ $this->acquireNodes(1);
+ //$this->fail("We now have ". count($this->nodes) ." nodes.");
$node = node_load($this->nodes[0]->nid);
$this->drupalGet('node/'. $this->nodes[0]->nid);
$edit = array();
- $edit[$field['field_name'] .'[0][url]'] = 'http://www.example.com';
+ $edit[$field['field_name'] .'[0][url]'] = $url;
$this->drupalPost('node/'. $this->nodes[0]->nid .'/edit', $edit, t('Save'));
+
+ // Make sure we get a new version!
+ $node = node_load($this->nodes[0]->nid, NULL, TRUE);
$this->assertText(t('@type @title has been updated.',
array('@title' => $node->title,
'@type' => $this->content_types[0]->name)));
- // Make sure we get a new version!
- $node = node_load($this->nodes[0]->nid, NULL, TRUE);
- $this->assertEqual('http://www.example.com', $node->{$field['field_name']}[0]['url']);
+ $this->assertEqual($url, $node->{$field['field_name']}[0]['url']);
+ }
+}
+
+class LinkValidateTest extends LinkValidateTestCase {
+
+ function getInfo() {
+ return array(
+ 'name' => t('Link Validation Tests'),
+ 'description' => t('Tests the field validation.'),
+ 'group' => t('Link'),
+ );
+ }
+
+ function test_link_validate_basic_url() {
+ $this->link_test_validate_url('http://www.example.com');
}
function test_link_validate_bad_url() {
@@ -95,9 +106,6 @@ class LinkValidateTest extends ContentCrudTestCase {
$node = node_load($this->nodes[0]->nid);
- /*$node->{$field['field_name']}[0] = $this->createLink('edik:naw', 'Test Link');
- node_save($node);*/
-
$this->drupalGet('node/'. $this->nodes[0]->nid);
$edit = array();
@@ -112,5 +120,68 @@ class LinkValidateTest extends ContentCrudTestCase {
$this->assertNotEqual('edik:naw', $node->{$field['field_name']}[0]['url']);
}
+
+ // Validate that '<front>' is a valid url.
+ function test_link_front_url() {
+ $this->link_test_validate_url('<front>');
+ }
+
+ // Validate that an internal url would be accepted.
+ function test_link_internal_url() {
+ $this->link_test_validate_url('node/32');
+ }
+
+ // Validate a simple mailto.
+ function test_link_mailto() {
+ $this->link_test_validate_url('mailto:jcfiala@gmail.com');
+ }
+
+ function test_link_external_https() {
+ $this->link_test_validate_url('https://www.example.com/');
+ }
+
+ function test_link_ftp() {
+ $this->link_test_validate_url('ftp://www.example.com/');
+ }
+}
+
+class LinkValidateTestNews extends LinkValidateTestCase {
+
+ function getInfo() {
+ return array(
+ 'name' => t('Link News Validation Tests'),
+ 'description' => t('Tests the field validation for usenet urls.'),
+ 'group' => t('Link'),
+ );
+ }
+
+ // Validate a news link to a message group
+ function test_link_news() {
+ $this->link_test_validate_url('news:comp.infosystems.www.misc');
+ }
+
+ // Validate a news link to a message id. Said ID copied off of google groups.
+ function test_link_news_message() {
+ $this->link_test_validate_url('news:hj0db8$vrm$1@news.eternal-september.org');
+ }
+}
+class LinkValidateSpecificURL extends LinkValidateTestCase {
+ function getInfo() {
+ return array(
+ 'name' => t('Link Unusual URL Validation Tests'),
+ 'description' => t('Tests field validation with unusual urls'),
+ 'group' => t('Link'),
+ );
+ }
+
+ // Lets throw in a lot of umlouts for testing!
+ function test_umlout_url() {
+ $this->link_test_validate_url('http://üÜü.exämple.com/nöde');
+ }
+
+ function test_umlout_mailto() {
+ $this->link_test_validate_url('mailto:Üser@exÅmple.com');
+ }
+
} \ No newline at end of file