App-SpamcupNG

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

  Change: ae712d3feb8a1c9bf07c95ac64250c90758b9d70
  Author: Alceu Rodrigues de Freitas Junior <glasswalk3r@yahoo.com.br>
  Date : 2022-03-23 00:09:21 +0000

    refactor: indicating expected tests 

  Change: e22c0be7241ef7fbd23382319cb31ee8a08e08f7
  Author: Alceu Rodrigues de Freitas Junior <glasswalk3r@yahoo.com.br>
  Date : 2022-03-23 00:06:43 +0000

    fix: not persisting charset

    Also added lock_hash to avoid hash key autovivification. Added unit
    tests to cover the class. 

  Change: 0b0c70ead698b143a9dadf6d55350cc8312018c3
  Author: Alceu Rodrigues de Freitas Junior <glasswalk3r@yahoo.com.br>
  Date : 2022-03-22 22:30:17 +0000

    feat: added unix epoch when summary was stored 

Changes  view on Meta::CPAN

  Change: 771793642f2158b0cdef255832d2830dd4e5548d
  Author: Alceu Rodrigues de Freitas Junior <glasswalk3r@yahoo.com.br>
  Date : 2022-03-20 14:24:03 +0000

    chore: added TODO 

  Change: e333a6e40d30eaf1f1b59640adf5d13971b83d94
  Author: Alceu Rodrigues de Freitas Junior <glasswalk3r@yahoo.com.br>
  Date : 2022-03-20 11:47:03 +0000

    feat: split charset from content-type 

  Change: 03ebc1c728569c71e1504957557795c1fe77667d
  Author: Alceu Rodrigues de Freitas Junior <glasswalk3r@yahoo.com.br>
  Date : 2022-03-20 11:43:04 +0000

    chore: module prereq 

  Change: fb701af0cd61a22674673e1f5337f6a245b75fdc
  Author: Alceu Rodrigues de Freitas Junior <glasswalk3r@yahoo.com.br>
  Date : 2022-03-19 14:16:01 +0000

Changes  view on Meta::CPAN


    fix: zero is an expected age

    Also validating the expected number of members/attributes the Summary
    class is expected to have. 

  Change: 0766d9794aef2ebc50caf2005ab08cf6d3d1b508
  Author: Alceu Rodrigues de Freitas Junior <glasswalk3r@yahoo.com.br>
  Date : 2022-03-05 00:31:42 +0000

    fix: normalizing charset

    Sometimes charset comes with double quotes, sometimes not. 

  Change: 085511fffe983fe0371f719a514db199fe14d9b4
  Author: Alceu Rodrigues de Freitas Junior <glasswalk3r@yahoo.com.br>
  Date : 2022-02-24 14:58:19 +0000

    Merge pull request #6 from glasswalk3r/refactor/user_agent

    Refactor/user agent 

  Change: 9e8ad58dc354228d9071dc6246a04bbfa4f11411

README.md  view on Meta::CPAN

    SUMMARY |o--o{ EMAIL_CHARSET : has
    SUMMARY ||--|| EMAIL_CONTENT_TYPE : has
    SUMMARY |o--o{ MAILER : has
    SUMMARY ||--|| SUMMARY_RECEIVER : has
    SUMMARY ||--|| SPAM_AGE_UNIT : has
    SUMMARY_RECEIVER ||--|| RECEIVER : relates-to
    SUMMARY {
        integer id PK
        string tracking_id UK
        integer created
        integer charset_id FK
        integer content_type_id FK
        integer age
        integer age_unit_id FK
        integer mailer_id FK
    }
    EMAIL_CHARSET {
        integer id PK
        string name
    }
    EMAIL_CONTENT_TYPE {

lib/App/SpamcupNG.pm  view on Meta::CPAN

    }

    my $form = _report_form( $response_ref, $base_uri );
    $logger->die(
'Could not find the HTML form to report the SPAM! May be a temporary Spamcop.net error, try again later! Quitting...'
    ) unless ( defined($form) );

    my $spam_header_info = find_header_info($response_ref);
    $summary->set_mailer( $spam_header_info->{mailer} );
    $summary->set_content_type( $spam_header_info->{content_type} );
    $summary->set_charset( $spam_header_info->{charset} );

    if ( $logger->is_info ) {
        $logger->info( 'X-Mailer: ' . $summary->to_text('mailer') );
        $logger->info( 'Content-Type: ' . $summary->to_text('content_type') );

        my $spam_header_ref = find_spam_header($response_ref);

        if ($spam_header_ref) {
            my $as_string = join( "\n", @$spam_header_ref );
            $logger->info("Head of the SPAM follows:\n$as_string");

lib/App/SpamcupNG/HTMLParse.pm  view on Meta::CPAN

                next;
            }

            if ( $content =~ $content_type_regex ) {
                my $wanted = ( split( ':', $content ) )[1];
                $wanted =~ s/^\s+//;
                my @wanted = split( ';', $wanted );

                if ( scalar(@wanted) > 1 ) {
                    my $encoding = lc( $wanted[0] );
                    my $charset  = lc( $wanted[1] );
                    $charset =~ s/^\s+//;
                    $charset =~ tr/"//d;

                    my $not_useful = 'boundary';

                    if (
                        substr( $charset, 0, length($not_useful) ) eq
                        $not_useful )
                    {
                        $info{content_type} = $encoding;
                        $info{charset}      = undef;
                    }
                    else {
                        $info{content_type} = $encoding;
                        $info{charset}      = ( split( '=', $charset ) )[1];
                    }
                }
                else {
                    chop $wanted if ( substr( $wanted, -1 ) eq ';' );
                    $info{content_type} = $wanted;
                }

                next;
            }

lib/App/SpamcupNG/Summary.pm  view on Meta::CPAN


Sometimes the C<receivers> addresses will not real ones, but "counters" that
will not be used for the report, but only for Spamcop statistics.

=cut

__PACKAGE__->follow_best_practice;
my $fields = Set::Tiny->new(
    (
        'tracking_id', 'mailer',   'content_type', 'age',
        'age_unit',    'contacts', 'receivers',    'charset'
    )
);
my $ro_fields = Set::Tiny->new(qw(receivers));

__PACKAGE__->mk_accessors( ( $fields->difference($ro_fields) )->members );
__PACKAGE__->mk_ro_accessors( $ro_fields->members );

=head1 METHODS

=head2 new

lib/App/SpamcupNG/Summary.pm  view on Meta::CPAN

sub new {
    my ( $class, $attribs_ref ) = @_;
    my $self = {
        tracking_id  => undef,
        mailer       => undef,
        content_type => undef,
        age          => undef,
        age_unit     => undef,
        contacts     => undef,
        receivers    => undef,
        charset      => undef
    };
    bless $self, $class;
    lock_keys( %{$self} );
    return $self;
}

=head2 as_text

Returns the summary attributes as strings, separated by commas.

lib/App/SpamcupNG/Summary/Recorder.pm  view on Meta::CPAN

        q{
CREATE TABLE IF NOT EXISTS spam_age_unit (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL UNIQUE
)
    }
    ) or confess $self->{dbh}->errstr;

    $self->{dbh}->do(
        q{
CREATE TABLE IF NOT EXISTS email_charset (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL UNIQUE
)
    }
    ) or confess $self->{dbh}->errstr;

    $self->{dbh}->do(
        q{
CREATE TABLE IF NOT EXISTS receiver (
  id INTEGER PRIMARY KEY AUTOINCREMENT,

lib/App/SpamcupNG/Summary/Recorder.pm  view on Meta::CPAN

)
    }
    ) or confess $self->{dbh}->errstr;

    $self->{dbh}->do(
        q{
CREATE TABLE IF NOT EXISTS summary (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  tracking_id TEXT NOT NULL UNIQUE,
  created INTEGER NOT NULL,
  charset_id INTEGER REFERENCES email_charset ON DELETE SET NULL,
  content_type_id INTEGER REFERENCES email_content_type ON DELETE SET NULL,
  age INTEGER NOT NULL,
  age_unit_id INTEGER REFERENCES spam_age_unit ON DELETE SET NULL,
  mailer_id INTEGER REFERENCES mailer ON DELETE SET NULL
)
    }
    ) or confess $self->{dbh}->errstr;

    $self->{dbh}->do(
        q{

lib/App/SpamcupNG/Summary/Recorder.pm  view on Meta::CPAN

=cut

sub save {
    my ( $self, $summary ) = @_;
    my $summary_class = 'App::SpamcupNG::Summary';
    my $ref           = ref($summary);
    confess "summary must be instance of $summary_class class, not '$ref'"
      unless ( $ref eq $summary_class );

    # TODO: create a method for Summary to provide those names
    my @fields = qw(content_type age_unit charset mailer);
    my %fields;

    foreach my $field_name (@fields) {
        my $method = "get_$field_name";
        $fields{$field_name} =
          $self->_save_attrib( $field_name, $summary->$method );
    }

    lock_hash(%fields);

lib/App/SpamcupNG/Summary/Recorder.pm  view on Meta::CPAN

VALUES(?, ?, ?)
        }, undef, @values
    ) or confess $self->{dbh}->errstr;
}

sub _save_summary {
    my ( $self, $summary, $fields_ref ) = @_;
    my $now    = $self->{now} ? $self->{now} : DateTime->now->epoch;
    my $insert = q{
INSERT INTO summary
(tracking_id, created, charset_id, content_type_id, age, age_unit_id, mailer_id)
VALUES (?, ?, ?, ?, ?, ?, ?)
};
    my @values = (
        $summary->get_tracking_id, $now,
        $fields_ref->{charset},    $fields_ref->{content_type},
        $summary->get_age,         $fields_ref->{age_unit},
        $fields_ref->{mailer}
    );
    $self->{dbh}->do( $insert, undef, @values )
      or confess $self->{dbh}->errstr;
    return $self->{dbh}->last_insert_id;
}

sub _save_attrib {
    my ( $self, $attrib, $value ) = @_;
    my %attrib_to_table = (
        content_type => 'email_content_type',
        age_unit     => 'spam_age_unit',
        charset      => 'email_charset',
        mailer       => 'mailer',
        receiver     => 'receiver'
    );

    return undef unless ( defined($value) );
    confess "'$attrib' is not a valid attribute"
      unless ( exists( $attrib_to_table{$attrib} ) );
    my $table = $attrib_to_table{$attrib};
    my $column;

lib/App/SpamcupNG/Summary/Recorder.pm  view on Meta::CPAN


    SELECT A.id,
      A.tracking_id,
      DATETIME(A.created, 'unixepoch') AS CREATED,
      B.name AS CHARSET,
      C.name AS CONTENT_TYPE,
      A.age,
      D.name AS MAILER,
      E.report_id,
      F.email
    FROM summary A outer left join email_charset B on A.charset_id = B.id
    INNER JOIN email_content_type C ON A.content_type_id = C.id
    OUTER LEFT JOIN mailer D ON A.mailer_id = D.id
    INNER JOIN summary_receiver E ON A.id = E.summary_id
    INNER JOIN receiver F ON E.receiver_id = F.id;

=head1 SEE ALSO

=over

=item *

t/find_header_info.t  view on Meta::CPAN

use lib './t';
use Fixture 'read_html';

my $source = 'sendreport_form_ok.html';
note($source);
my $result = find_header_info( read_html($source) );
is( ref($result),      'HASH',             'result is a hash reference' );
is( $result->{mailer}, 'Smart_Send_4_4_2', 'mailer has the expected value' );
is( $result->{content_type},
    'multipart/mixed', 'content_type has the expected value' );
is( $result->{charset}, undef, 'charset has the expected value' );

$source = 'missing_sendreport_form.html';
note($source);
$result = find_header_info( read_html($source) );
is( ref($result),      'HASH', 'result is a hash reference' );
is( $result->{mailer}, undef,  'mailer has the expected value' );
is( $result->{content_type},
    'multipart/alternative', 'content_type has the expected value' );
is( $result->{charset}, 'utf-8', 'charset has the expected value' );

$source = 'boundary.html';
note($source);
$result = find_header_info( read_html($source) );
is( ref($result),      'HASH', 'result is a hash reference' );
is( $result->{mailer}, undef,  'mailer has the expected value' );
is( $result->{content_type},
    'multipart/alternative', 'content_type has the expected value' );
is( $result->{charset}, undef, 'charset has the expected value' );

# vim: filetype=perl

t/recorder.t  view on Meta::CPAN

use Test::TempDir::Tiny;
use DBI;

use App::SpamcupNG::Summary;
use App::SpamcupNG::Summary::Receiver;
use App::SpamcupNG::Summary::Recorder;

my $summary = App::SpamcupNG::Summary->new;
$summary->set_age_unit('hour');
$summary->set_age(2);
$summary->set_charset('utf-8');
$summary->set_content_type('text/html');
$summary->set_mailer('WebService/1.1.18749 YMailNorrin');
$summary->set_tracking_id('z6746172301zed5b6b1ebead7134e06e5ae08cc87e0cz');
$summary->set_receivers(
    [
        [ 'report_spam@hotmail.com',       7173783708 ],
        [ 'junk@office365.microsoft.com',  7173783709 ],
        [ 'abuse@messaging.microsoft.com', 7173783710 ]
    ]
);

t/recorder.t  view on Meta::CPAN

ok( $recorder->init,           'database is properly initialized' );
ok( $recorder->save($summary), 'a summary is properly persisted' );
note('Now forcing database to be persisted on disk');
$recorder->{dbh}->disconnect;

note('Now checking what is on DB');
my $dbh             = DBI->connect( "dbi:SQLite:dbname=$db_file", '', '' );
my $result_ref      = query_all_tables($dbh);
my @expected_tables = (
    'email_content_type', 'spam_age_unit',
    'email_charset',      'receiver',
    'mailer',             'summary',
    'summary_receiver'
);
is_deeply( $result_ref, \@expected_tables, 'got the expected tables' );

my %expected_results;

@expected_results{@expected_tables} = (
    [ 1, 'text/html' ],
    [ 1, 'hour' ],

t/responses/after_login.html  view on Meta::CPAN

<p><strong><a href="/mcgi?action=paymenu">Add fuel to your account</a></strong><br>
Please help support this service - buy some reporting fuel today. Fuel is used as you report spam to bypass the nag
screen.</p>
<p><strong>Unreported Spam Saved: <a href="/sc?id=z6444645586z5cebd61f7e0464abe28f045afff01b9dz">Report
Now</a></strong><br>
You have submitted spam which has not yet been reported. Please avoid re-reporting spam. If you have already reported
this spam or do not want to report it, please make sure to click "cancel" instead of submitting the report!<br>
<a href="/w3m?action=removeunreported&amp;authcode=w9n2BBgCTP3Enrh3" onclick="return sure()">Remove all unreported
spam</a></p>
<form method="post" action="/sc" name="submitspam" onsubmit="return formval(50000);" enctype="multipart/form-data"
accept="text/plain" accept-charset="UTF-8"><input type="hidden" name="action" value="submit"> <input type="hidden"
name="oldverbose" value="1"> Forward your spam to: <a href=
"mailto:submit.w9n2BBgCTP3Enrh3@spam.spamcop.net">submit.w9n2BBgCTP3Enrh3@spam.spamcop.net</a> or:<br>
Paste entire spam (headers, blank line, body) - or - single address (one line only):<br>
<textarea class="widetext" name="spam" rows="7" cols="80" wrap="off"></textarea>
<br>
<input type="submit" name="x1" value="Process Spam"> <input type="reset" name="x2" value="Clear Form"> <input type=
"checkbox" name="verbose" value="1" checked>Show technical details</form>
<p><a href="/w3m?action=outhouse;value=1">Select outlook/eudora workaround form</a></p>
<p><strong>News:</strong> (Last Modified: <noscript>Tue Jan 9 05:25:21 2018 GMT</noscript> 
<script>

t/responses/boundary.html  view on Meta::CPAN

Recurse multipart:<br>
&nbsp;&nbsp;&nbsp;Parsing text part<br>
&nbsp;&nbsp;&nbsp;Parsing HTML part<br>
&nbsp;&nbsp;&nbsp;No html links found, trying text parse<br>
no links found<br>
<a name="report"></a><p><strong>
Please make sure this email IS spam:
</strong><br>
<font face="courier" size=2>
From: Alberto &lt;jolymax017@gmail.com&gt; (<strong>/...Can You Partner With me?..</strong>)<br>
&nbsp;--00000000000031c69105d8096fb1<br>&nbsp;Content-Type: text/plain; charset="UTF-8"<br>
</font><a href="/sc?id=z6741667206z192b71f03a7fd05d2709b01084d24fa3z&action=display">
View full message</a><p>

<form action="/sc" method="post"
  enctype="multipart/form-data" name="sendreport">
<input type="hidden" name="action" value="flexsend">
<input type="hidden" name="spamid" value="6741667206">
<input type="hidden" name="crc" value="192b71f03a7fd05d2709b01084d24fa3">
<input type="hidden" name="date" value="Tue, 15 Feb 2022 07:25:16 +0000">
<input type="hidden" name="source" value="209.85.167.47">

t/responses/mailhost_problem.html  view on Meta::CPAN

	id DvUa1x00C3akymp01vUaLq; Thu, 22 Feb 2018 19:28:35 +0000
Received: from mzkstore626.ocn.ad.jp (mz-ukg626p.ocn.ad.jp [153.149.212.195])
	by vcwebmail.ocn.ad.jp (Postfix) with ESMTP;
	Fri, 23 Feb 2018 04:28:34 +0900 (JST)
Date: Fri, 23 Feb 2018 04:28:34 +0900 (JST)
From: =?utf-8?Q?USU=C3=81RIO?= DE NOME DA NACION &lt;info.@vanilla.ocn.ne.jp&gt;
Reply-To: p.heymann@yandex.by
Message-ID: &lt;6898_____________________________________root@vanilla.ocn.ne.jp&gt;
Subject: =?utf-8?Q?ATEN=C3=87=C3=83O_QUERIDO_BENEFICI=C3=81RIO?=
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Originating-IP: [41.138.89.250]</pre>
<a href="/sc?id=z6447728584zdce3060bf07717c198a7005ac6d480e3z;action=display">
View entire message</a>
<div class="header">Parsing header:</div>
host 2002:a17:902:b185:0:0:0:0 (getting name)
no name<br>
<div class="fixedmsg">0: Received: by 2002:a17:902:b185:: with SMTP id s5-v6mr2972105plr.109.1519328269958; Thu, 22 Feb 2018 11:37:49 -0800 (PST)</div>
No unique hostname found for source: 2002:a17:902:b185:0:0:0:0<br>
<div class="warning">Possible forgery. Supposed receiving system not associated with any of your mailhosts</div>

t/responses/missing_sendreport_form.html  view on Meta::CPAN

Message-ID: &lt;2737________________________f0d9@bemimob.com.br&gt;
Date: Fri, 29 Oct 2021 16:05:26 +0000
From: "=?UTF-8?B?VG9nbmF0byAtIEJlbSBJbW9iaWxpw6FyaWE=?=" &lt;tognato@bemimob.com.br&gt;
Reply-To: tognato@bemparcerias.com.br
MIME-Version: 1.0
X-Mailer-LID: 29,30,23,28,25,24
List-Unsubscribe: &lt;https://bemimob.com.br/emkt/unsubscribe.php?M=1759364&amp;C=da6e868ae50b14b880bbf707baa6c7cd&amp;L=24&amp;N=94&gt;
X-Mailer-RecptId: 1759364
X-Mailer-SID: 94
X-Mailer-Sent-By: 2
Content-Type: multipart/alternative; charset="UTF-8"; boundary="b1_26676889acbe3451079e0b567bd9271f"
Content-Transfer-Encoding: 8bit</pre>
<a href="/sc?id=z6728333544zfadf3621d490ea840a52ae9b28e37703z;action=display">
View entire message</a>
<div class="header">Parsing header:</div>
<div class="fixedmsg">0: Received: from 10.196.243.13 by atlas317.free.mail.bf1.yahoo.com with HTTPS; Fri, 29 Oct 2021 18:31:11 +0000</div>
Internal handoff at YahooMain<br>
<br>
<div class="fixedmsg">1: Received: from 5.196.136.237 (EHLO mta0.bemimob.com.br) by 10.196.243.13 with SMTP; Fri, 29 Oct 2021 18:31:11 +0000</div>
Hostname verified: mta0.bemimob.com.br<br>
YahooMain received mail from sending system 5.196.136.237<br>

t/responses/reports_disabled.html  view on Meta::CPAN

                    Report Now</a></strong>
            <br>You have submitted spam which has not yet been reported.
            Please avoid re-reporting spam. If you have already reported this
            spam or do not want to report it, please make sure to click "cancel"
            instead of submitting the report!

            <br><a href="/w3m?action=removeunreported&authcode=w9n2BBgCTP3Enrh3" onclick="return sure()">
                Remove all unreported spam</a>
        <p>
        <form method="post" action="/sc" name="submitspam" onsubmit="return formval(50000);"
            enctype="multipart/form-data" accept="text/plain" accept-charset="UTF-8">
            <input type="hidden" name="action" value="submit">
            <input type="hidden" name="oldverbose" value="1">
            Forward your spam to: <a href="mailto:submit.w9n2BBgCTP3Enrh3@spam.spamcop.net">
                submit.w9n2BBgCTP3Enrh3@spam.spamcop.net</a> or:
            <br>
            Paste entire spam (headers, blank line, body) - or - single address (one line only):
            <br>
            <textarea class="widetext" name="spam" rows=7 cols=80 wrap="off"></textarea><br>

            <input type="submit" name="x1" value="Process Spam">

t/responses/sequence/1.html  view on Meta::CPAN

spam or do not want to report it, please make sure to click "cancel"
instead of submitting the report!

<br><a href="/w3m?action=removeunreported&authcode=w9n2BBgCTP3Enrh3"
 onclick="return sure()">
Remove all unreported spam</a>
<p><form method="post" action="/sc" name="submitspam"
  onsubmit="return formval(50000);"
  enctype="multipart/form-data"
  accept="text/plain"
  accept-charset="UTF-8">
<input type="hidden" name="action" value="submit">
<input type="hidden" name="oldverbose" value="1">
Forward your spam to: <a href="mailto:submit.w9n2BBgCTP3Enrh3@spam.spamcop.net">
submit.w9n2BBgCTP3Enrh3@spam.spamcop.net</a> or:
<br>
Paste entire spam (headers, blank line, body) - or - single address (one line only):
<br>
<textarea class="widetext" name="spam" rows=7 cols=80
 wrap="off"></textarea><br>

t/responses/sequence/2.html  view on Meta::CPAN

 Tue, 23 Nov 2021 22:51:49 -0800 (PST)
MIME-Version: 1.0
Received: by 2002:a05:6512:2286:0:0:0:0 with HTTP; Tue, 23 Nov 2021 22:51:49
 -0800 (PST)
Reply-To: harvey2roy@gmail.com
From: MS ELIZA NISSAN &lt;sbarley110@gmail.com&gt;
Date: Wed, 24 Nov 2021 07:51:49 +0100
Message-ID: &lt;CAER___________________________________________9rPw@mail.gmail.com&gt;
Subject: My Compensation
To: undisclosed-recipients:;
Content-Type: text/plain; charset="UTF-8"</pre>
<a href="/sc?id=z6731356012zdc1bc09296ac2635b0861f61911073e5z;action=display">
View entire message</a>
<div class="header">Parsing header:</div>
<div class="fixedmsg">0: Received: from 10.217.136.18 by atlas122.free.mail.ne1.yahoo.com with HTTPS; Wed, 24 Nov 2021 06:51:50 +0000</div>
Internal handoff at YahooMain<br>
<br>
<div class="fixedmsg">1: Received: from 209.85.167.48 (EHLO mail-lf1-f48.google.com) by 10.217.136.18 with SMTPs (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256); Wed, 24 Nov 2021 06:51:50 +0000</div>
Hostname verified: mail-lf1-f48.google.com<br>
YahooMain received mail from YahooMain ( 209.85.167.48 )<br>
<br>

t/responses/sequence/4.html  view on Meta::CPAN

Pretty good!
<p><strong><a href="/mcgi?action=paymenu">
Add fuel to your account</a></strong>
<br>Please help support this service - buy some reporting fuel today.
  Fuel is used as you report spam to bypass the nag screen.

<p><form method="post" action="/sc" name="submitspam"
  onsubmit="return formval(50000);"
  enctype="multipart/form-data"
  accept="text/plain"
  accept-charset="UTF-8">
<input type="hidden" name="action" value="submit">
<input type="hidden" name="oldverbose" value="1">
Forward your spam to: <a href="mailto:submit.w9n2BBgCTP3Enrh3@spam.spamcop.net">
submit.w9n2BBgCTP3Enrh3@spam.spamcop.net</a> or:
<br>
Paste entire spam (headers, blank line, body) - or - single address (one line only):
<br>
<textarea class="widetext" name="spam" rows=7 cols=80
 wrap="off"></textarea><br>

t/summary.t  view on Meta::CPAN


use App::SpamcupNG::Summary;

my $instance = new_ok('App::SpamcupNG::Summary');
can_ok( $instance,
    qw(new as_text tracking_url to_text set_receivers _fields) );
is( ref( $instance->_fields ),
    'ARRAY', '_fields method returns the expected reference type' );
my @expected_fields = sort( (
        'tracking_id', 'mailer',   'content_type', 'age',
        'age_unit',    'contacts', 'receivers',    'charset'
) );
is_deeply( $instance->_fields, \@expected_fields,
    'fields returns all expected members' );
note('summary with nothing set');
is(
    $instance->as_text,
'age_unit=not available,charset=not available,content_type=not available,mailer=not available,tracking_id=not available,age=not available,receivers=(),contacts=()',
    'as_text returns the expected empty instance'
);
is(
    $instance->to_text('mailer'),
    'not available',
    'to_text returns the expected string'
);
is( $instance->to_text('contacts'),
    '()', 'to_text returns the expected string' );

t/summary.t  view on Meta::CPAN

is(
    $instance->tracking_url,
    "https://www.spamcop.net/sc?id=$tracking_id",
    'tracking URL is the expected'
);
my $mailer = 'Foobar Mailer';
ok( $instance->set_mailer($mailer), 'set mailer' );
is( $instance->to_text('mailer'),
    $mailer, 'to_text returns the expected string' );
ok( $instance->set_content_type('text/plain'), 'set content type' );
ok( $instance->set_charset('utf-8'),           'set charset' );
ok( $instance->set_age(2),                     'set age' );
ok( $instance->set_age_unit('hour'),           'set age unit' );
my $emails_ref = [ 'john@gmail.com', 'doe@gmail.com' ];
my $report_id  = 7164185194;
my @receivers  = map { [ $_, ++$report_id ] } @{$emails_ref};
ok( $instance->set_receivers( \@receivers ), 'set receivers' );
is(
    $instance->to_text('receivers'),
    'receivers=((john@gmail.com,7164185195);(doe@gmail.com,7164185196))',
    'to_text returns the expected string'
);
ok( $instance->set_contacts($emails_ref), 'set contacts' );
is(
    $instance->to_text('contacts'),
    '(john@gmail.com;doe@gmail.com)',
    'to_text returns the expected string'
);
note('summary with everything set');
is(
    $instance->as_text,
"age_unit=hour,charset=utf-8,content_type=text/plain,mailer=Foobar Mailer,tracking_id=$tracking_id,age=2,receivers=((john\@gmail.com,7164185195);(doe\@gmail.com,7164185196)),contacts=(john\@gmail.com;doe\@gmail.com)",
    'as_text returns the expected string'
);

note('summary with reports with age less than one hour');
$instance->set_age(0);
is(
    $instance->as_text,
"age_unit=hour,charset=utf-8,content_type=text/plain,mailer=Foobar Mailer,tracking_id=$tracking_id,age=0,receivers=((john\@gmail.com,7164185195);(doe\@gmail.com,7164185196)),contacts=(john\@gmail.com;doe\@gmail.com)",
    'as_text returns the expected string'
);

# undoing
$instance->set_age(2);
note('summary with missing sent reports ID');
@receivers = ();
@receivers = map { [ $_, undef ] } @{$emails_ref};
ok( $instance->set_receivers( \@receivers ), 'set receivers' );
is(
    $instance->as_text,
"age_unit=hour,charset=utf-8,content_type=text/plain,mailer=Foobar Mailer,tracking_id=$tracking_id,age=2,receivers=((john\@gmail.com,not available);(doe\@gmail.com,not available)),contacts=(john\@gmail.com;doe\@gmail.com)",
    'as_text returns the expected string'
);

# vim: filetype=perl



( run in 0.388 second using v1.01-cache-2.11-cpan-4d50c553e7e )