Email-Abuse-Investigator
view release on metacpan or search on metacpan
t/mutation_survivors.t view on Meta::CPAN
is $r_str, 'hello', '_sanitise_output("hello") returns "hello" exactly';
isnt $r_str, '', '_sanitise_output("hello") does not return empty string (negation)';
# C0-stripped string: must return the stripped string (not its negation)
my $r_ctrl = $fn->("\x01hello\x02");
is $r_ctrl, 'hello', '_sanitise_output strips controls and returns stripped string';
isnt $r_ctrl, '', 'stripped result is not empty string (negation)';
};
# =============================================================================
# 38. _decode_body() return value [BOOL_NEGATE_2883_2]
# =============================================================================
subtest 'BOOL_NEGATE_2883_2 -- _decode_body() returns correct string' => sub {
my $a = Email::Abuse::Investigator->new();
# 7bit: returns body unchanged
my $r = $a->_decode_body('hello world', '7bit');
is $r, 'hello world', '_decode_body 7bit returns body string exactly';
isnt $r, '', '_decode_body 7bit does not return empty string';
# undef body: returns '' (not !'')
my $r_undef = $a->_decode_body(undef, '7bit');
is $r_undef, '', '_decode_body undef body returns empty string';
};
# =============================================================================
# 39. _header_value() return values [BOOL_NEGATE_4069_3, BOOL_NEGATE_4071_2]
# =============================================================================
subtest 'BOOL_NEGATE_4069/4071 -- _header_value() exact return values' => sub {
my $a = Email::Abuse::Investigator->new();
$a->parse_email("From: sender\@example.com\nSubject: Test Subject\n\nbody");
# Found header: returns the value string exactly
my $from = $a->_header_value('from');
is $from, 'sender@example.com',
'_header_value returns the exact header value string';
isnt $from, '', 'found header does not return empty string (negation)';
# Not found: returns undef exactly (not !undef = 1)
my $missing = $a->_header_value('x-no-such-header');
is $missing, undef,
'_header_value returns undef for missing header';
isnt $missing, 1, 'missing header does not return 1 (negation of undef)';
};
# =============================================================================
# 40. _decode_mime_words() return values [BOOL_NEGATE_4114_2, BOOL_NEGATE_4117_2]
# =============================================================================
subtest 'BOOL_NEGATE_4114/4117 -- _decode_mime_words() exact return values' => sub {
my $a = Email::Abuse::Investigator->new();
# undef: returns '' exactly
my $r_undef = $a->_decode_mime_words(undef);
is $r_undef, '', '_decode_mime_words(undef) returns empty string exactly';
isnt $r_undef, 1, 'not 1 (negation of empty string)';
# plain string: returned unchanged
my $r_plain = $a->_decode_mime_words('plain text');
is $r_plain, 'plain text', '_decode_mime_words returns plain string unchanged';
# encoded word: returns decoded string
my $enc = '=?UTF-8?B?' . encode_base64('decoded', '') . '?=';
my $r_enc = $a->_decode_mime_words($enc);
is $r_enc, 'decoded', '_decode_mime_words returns decoded string exactly';
isnt $r_enc, '', 'decoded string is not empty (negation)';
};
# =============================================================================
# 41. unresolved_contacts() conditions [COND_INV_1176_3, BOOL_NEGATE_1217_2]
# =============================================================================
subtest 'COND_INV_1176_3 + BOOL_NEGATE_1217_2 -- unresolved_contacts() branches' => sub {
null_net();
no warnings 'redefine';
local *Email::Abuse::Investigator::_domain_whois = sub { undef };
local *Email::Abuse::Investigator::_resolve_host = sub { undef };
local *Email::Abuse::Investigator::_whois_ip = sub { {} }; # no abuse
my $a = Email::Abuse::Investigator->new();
$a->parse_email("From: x\@y.com\n\nhttps://mystery.example/page and info\@mystery.example");
my @unresolved = $a->unresolved_contacts();
# Return value is a list (BOOL_NEGATE: not !list)
ok scalar @unresolved >= 0, 'unresolved_contacts() returns a list (not negation)';
# mystery.example has no abuse contact so should appear
ok scalar(grep { $_->{domain} eq 'mystery.example' } @unresolved),
'mystery.example (no abuse contact) appears in unresolved_contacts()';
# Each entry has the required keys (COND_INV_1176_3: dom extraction)
for my $u (@unresolved) {
ok defined $u->{domain}, "entry has domain (got '$u->{domain}')";
ok defined $u->{type}, "entry has type";
ok defined $u->{source}, "entry has source";
}
restore_net();
};
done_testing();
( run in 0.555 second using v1.01-cache-2.11-cpan-a9496e3eb41 )