mod common;
use codoseo_core::Url;
use codoseo_core::page::{Indexability, PageFields, indexability, is_nofollow, is_noindex};
use common::sample_record;
#[test]
fn robots_directives() {
assert!(is_noindex(Some("NoIndex, follow"), None));
assert!(is_noindex(None, Some("none")));
assert!(is_noindex(None, Some("googlebot: noindex")));
assert!(!is_noindex(None, Some("bingbot: noindex"))); assert!(is_noindex(None, Some("codoseobot: noindex")));
assert!(!is_noindex(Some("index, follow"), None));
assert!(is_nofollow(Some("noindex,nofollow"), None));
assert!(is_nofollow(None, Some("none")));
assert!(!is_nofollow(Some("index"), None));
}
#[test]
fn agent_prefix_scopes_the_directives_after_it() {
let other = Some("otherbot: noindex, nofollow");
assert!(!is_noindex(other, None) && !is_nofollow(other, None));
assert!(!is_noindex(Some("bingbot: nofollow, noindex"), None));
assert!(!is_noindex(None, Some("bingbot: nofollow, noindex")));
let mixed = Some("googlebot: noindex, bingbot: nofollow");
assert!(is_noindex(mixed, None) && !is_nofollow(mixed, None));
assert!(is_noindex(None, mixed) && !is_nofollow(None, mixed));
let lead = Some("noindex, otherbot: nofollow");
assert!(is_noindex(lead, None) && !is_nofollow(lead, None));
assert!(is_nofollow(Some("codoseobot: index, nofollow"), None));
assert!(is_noindex(Some("googlebot: index, noindex"), None));
}
#[test]
fn value_directives_are_not_agent_prefixes() {
assert!(is_noindex(
Some("unavailable_after: 25 Jun 2010 15:00:00 PST, noindex"),
None
));
assert!(is_nofollow(Some("max-snippet: 20, nofollow"), None));
assert!(is_nofollow(
None,
Some("Max-Image-Preview: large, nofollow")
));
assert!(is_noindex(Some("max-video-preview: 5, noindex"), None));
assert!(!is_noindex(
Some("otherbot: max-snippet: 20, noindex"),
None
));
}
#[test]
fn indexability_status_boundaries() {
let u = Url::parse("https://e.com/a").unwrap();
let f = PageFields::default();
let at = |status| indexability(&u, status, &f, false);
assert_eq!(at(199), Indexability::ServerError);
assert_eq!(at(200), Indexability::Indexable);
assert_eq!(at(299), Indexability::Indexable);
assert_eq!(at(300), Indexability::Redirected);
assert_eq!(at(399), Indexability::Redirected);
assert_eq!(at(400), Indexability::ClientError);
assert_eq!(at(499), Indexability::ClientError);
assert_eq!(at(500), Indexability::ServerError);
assert_eq!(at(599), Indexability::ServerError);
assert_eq!(at(600), Indexability::ServerError);
}
#[test]
fn indexability_rules() {
let u = Url::parse("https://e.com/a").unwrap();
let f = PageFields::default();
assert_eq!(indexability(&u, 200, &f, false), Indexability::Indexable);
assert_eq!(
indexability(&u, 200, &f, true),
Indexability::BlockedByRobots
);
assert_eq!(indexability(&u, 301, &f, false), Indexability::Redirected);
assert_eq!(indexability(&u, 404, &f, false), Indexability::ClientError);
assert_eq!(indexability(&u, 0, &f, false), Indexability::ServerError);
assert_eq!(indexability(&u, 503, &f, false), Indexability::ServerError);
assert_eq!(indexability(&u, 100, &f, false), Indexability::ServerError);
let ni = PageFields {
meta_robots: Some("noindex".into()),
..Default::default()
};
assert_eq!(indexability(&u, 200, &ni, false), Indexability::Noindex);
let header_ni = PageFields {
x_robots_tag: Some("noindex".into()),
..Default::default()
};
assert_eq!(
indexability(&u, 200, &header_ni, false),
Indexability::Noindex
);
let canon = PageFields {
canonical: Some(Url::parse("https://e.com/b").unwrap()),
..Default::default()
};
assert_eq!(
indexability(&u, 200, &canon, false),
Indexability::Canonicalised
);
let self_canon = PageFields {
canonical: Some(u.clone()),
..Default::default()
};
assert_eq!(
indexability(&u, 200, &self_canon, false),
Indexability::Indexable
);
}
#[test]
fn key_hash_tracks_content_not_timing() {
let mut p = sample_record();
let k = p.compute_key_hash();
p.response_ms += 500;
assert_eq!(p.compute_key_hash(), k);
p.fields.title = Some("Other".into());
assert_ne!(p.compute_key_hash(), k);
let mut q = sample_record();
q.in_sitemap = true;
assert_ne!(q.compute_key_hash(), k);
let mut r = sample_record();
r.redirect_target = Some(Url::parse("https://e.com/z").unwrap());
assert_ne!(r.compute_key_hash(), k);
}
#[test]
fn key_hash_separates_adjacent_fields() {
let mut a = sample_record();
a.fields.title = Some("ab".into());
a.fields.meta_description = None;
let mut b = sample_record();
b.fields.title = Some("a".into());
b.fields.meta_description = Some("b".into());
assert_ne!(a.compute_key_hash(), b.compute_key_hash());
}
#[test]
fn html_ok_rules() {
assert!(sample_record().is_html_ok());
let mut p = sample_record();
p.content_type = None;
assert!(p.is_html_ok());
p.content_type = Some("application/pdf".into());
assert!(!p.is_html_ok());
let mut p = sample_record();
p.status = 404;
assert!(!p.is_html_ok());
let mut p = sample_record();
p.error = Some(codoseo_core::page::FetchFailure::Timeout);
assert!(!p.is_html_ok());
}