Email-Abuse-Investigator
view release on metacpan or search on metacpan
t/function.t view on Meta::CPAN
));
$a->{_origin} = {
ip => '91.198.174.42', rdns => 'dial.residential.isp.example',
org => 'Bad ISP', abuse => 'abuse@bad-isp.example',
confidence => 'high', note => 'First hop', country => 'NG',
};
no warnings 'redefine';
local *Email::Abuse::Investigator::_resolve_host = sub { '1.2.3.4' };
local *Email::Abuse::Investigator::_whois_ip = sub { { org=>'Spam Host', abuse=>'abuse@spam.example' } };
local *Email::Abuse::Investigator::_domain_whois = sub { undef };
my $text = $a->abuse_report_text();
like $text, qr/automated abuse report/i, 'report intro present';
like $text, qr/RISK LEVEL/, 'RISK LEVEL present';
like $text, qr/ORIGINATING IP.*91\.198\.174\.42/s,'originating IP present';
like $text, qr/ORIGINAL MESSAGE HEADERS/, 'headers section present';
like $text, qr/from:/i, 'from header included';
# No contacts branch (all unknown)
my $b = Email::Abuse::Investigator->new();
$b->parse_email(make_email());
$b->{_origin} = { ip=>'1.2.3.4', rdns=>'mail.ok',
confidence=>'high', org=>'X', abuse=>'(unknown)',
note=>'', country=>undef };
$b->{_urls} = [];
$b->{_mailto_domains} = [];
my $text2 = $b->abuse_report_text();
like $text2, qr/RISK LEVEL/, 'report generated even without contacts';
}
# ===========================================================================
# 27. report() â all sections and branches
# ===========================================================================
note '=== 27. report() ===';
{
# Full report with encoded headers, shortener, multiple URLs
my $enc_subj = '=?UTF-8?B?' . encode_base64('Ready to Find Love', '') . '?=';
my $a = Email::Abuse::Investigator->new();
$a->parse_email(make_email(
from => 'Spammer <spammer@gmail.com>',
subject => $enc_subj,
body => 'https://bit.ly/spam and http://spamsite.example/buy',
received => 'from spammer (spammer [120.88.161.249]) by mx',
auth => 'mx; spf=fail; dkim=fail',
));
$a->{_origin} = {
ip => '120.88.161.249', rdns => '120-88-161-249.tpgi.com.au',
org => 'TPG Internet', abuse => 'abuse@tpg.com.au',
confidence => 'medium', note => 'First hop', country => 'AU',
};
no warnings 'redefine';
local *Email::Abuse::Investigator::_resolve_host = sub { '1.2.3.4' };
local *Email::Abuse::Investigator::_whois_ip = sub { { org=>'Test Org', abuse=>'abuse@testorg.example', country=>'US' } };
local *Email::Abuse::Investigator::_domain_whois = sub { undef };
my $report = $a->report();
like $report, qr/Email::Abuse::Investigator Report/, 'report title';
like $report, qr/RISK ASSESSMENT/, 'risk section';
like $report, qr/ORIGINATING HOST/, 'originating host section';
like $report, qr/120\.88\.161\.249/, 'originating IP';
like $report, qr/EMBEDDED HTTP\/HTTPS URLs/, 'url section';
like $report, qr/URL SHORTENER/, 'shortener warning';
like $report, qr/CONTACT \/ REPLY-TO DOMAINS/, 'domains section';
like $report, qr/WHERE TO SEND ABUSE REPORTS/, 'contacts section';
like $report, qr/Ready to Find Love/, 'encoded subject decoded';
# No-origin path
my $b = Email::Abuse::Investigator->new();
$b->parse_email("From: x\@y.com\nSubject: s\n\nbody");
$b->{_origin} = undef;
$b->{_urls} = [];
$b->{_mailto_domains} = [];
my $r2 = $b->report();
like $r2, qr/could not determine originating IP/, 'no-origin message';
like $r2, qr/none found/, 'no-urls message';
# Multiple URLs same host -> grouped
my $c = Email::Abuse::Investigator->new();
$c->parse_email(make_email(body => 'https://multi.example/a and https://multi.example/b'));
$c->{_origin} = { ip=>'1.2.3.4', rdns=>'mail.ok',
confidence=>'high', org=>'X', abuse=>'a@b',
note=>'', country=>undef };
no warnings 'redefine';
local *Email::Abuse::Investigator::_resolve_host = sub { '1.2.3.4' };
local *Email::Abuse::Investigator::_whois_ip = sub { { org=>'T', abuse=>'a@b' } };
local *Email::Abuse::Investigator::_domain_whois = sub { undef };
my $r3 = $c->report();
like $r3, qr/URLs \(2\)/, 'multiple URLs grouped under host';
# Contact domain with all sub-sections present
my $d = Email::Abuse::Investigator->new();
$d->parse_email(make_email(from => 'x@example-domain.tld'));
$d->{_origin} = { ip=>'1.2.3.4', rdns=>'mail.ok',
confidence=>'high', org=>'X', abuse=>'a@b',
note=>'', country=>undef };
$d->{_urls} = [];
$d->{_mailto_domains} = [{
domain => 'example-domain.tld',
source => 'From: header',
recently_registered => 1,
registered => '2025-12-01',
expires => '2026-12-01',
registrar => 'NameCheap',
registrar_abuse => 'abuse@namecheap.com',
web_ip => '5.5.5.5',
web_org => 'Host Co',
web_abuse => 'abuse@hostco.example',
mx_host => 'mail.example-domain.tld',
mx_ip => '6.6.6.6',
mx_org => 'Mail Co',
mx_abuse => 'abuse@mailco.example',
ns_host => 'ns1.example-domain.tld',
ns_ip => '7.7.7.7',
ns_org => 'NS Co',
ns_abuse => 'abuse@nsco.example',
}];
no warnings 'redefine';
local *Email::Abuse::Investigator::_resolve_host = sub { undef };
local *Email::Abuse::Investigator::_domain_whois = sub { undef };
my $r4 = $d->report();
like $r4, qr/RECENTLY REGISTERED/, 'recently_registered warning present';
( run in 0.308 second using v1.01-cache-2.11-cpan-71847e10f99 )